递归TODO

反向递归(和模拟不同,模拟是正向思维)

要求的是第n行第k个,可以反向向n-1行寻找答案
示例代码:
public int kthGrammar(int n, int k) {
if (n == 1) {
return 0;
}//递归出口
int parent = kthGrammar(n - 1, (k + 1) / 2);
if (parent == 0) {
return k % 2 == 1 ? 0 : 1;
} else {
return k % 2 == 1 ? 1 : 0;
}
}

一些思考了很久的思考

1.1 什么地方会用到递归
二叉树:计算一棵二叉树的最大深度=max(左子树的最大深度,右子树的最大深度)+1;而在计算每一个的时候,也可以用到相同方法
1.2 定义(重要)
由于子问题的规模比原问题小,不断 递 下去,总会有个尽头。即递归的 边界条件 直接返回它的答案,归
所以写一个递归程序的关键是 关系式和出口
tips:关系式有几个,就有几个出口
1.3 本质是数学归纳法
1.4 和栈的原理有点像
1.5 用递归写 数字 翻译成英文
public class NumberToWord {
private static final String[] LESS_THAN_20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
private static final String[] TENS = {"", "", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
private static final String[] THOUSANDS = {"", "Thousand", "Million", "Billion"};//构造静态数组(final让它不能被改变)

public static String numberToWords(int num) {
if (num == 0) return "Zero";
return helper(num, 0).trim();//。trim()可以让输出去掉开头和结尾的空字符,输出更简洁
}

private static String helper(int num, int i) {
if (num == 0) return "";
String res = "";
if (num % 1000 != 0) {
res = helperThreeDigits(num % 1000) + THOUSANDS[i] + " ";
}
return helper(num / 1000, i + 1) + res;
}//可以把很长的数字分割成一个个小的来方便处理

private static String helperThreeDigits(int num) {
String res = "";
if (num >= 100) {
res += LESS_THAN_20[num / 100] + " Hundred ";
num %= 100;
}
if (num >= 20) {
res += TENS[num / 10] + " ";
num %= 10;
}
if (num > 0) {
res += LESS_THAN_20[num] + " ";
}
return res;
}//计算每一个小的部分

}

1.5 继续理解!
递归的每次调用函数都会在栈里面开辟一个空间
举例


执行完一个函数之后就会弹栈,或通过下图理解

例2


m5=5m4,m4=4m3,m3=3m2,m2=2m1,m1=1

递归函数中可分为三个区域
1.调用递归函数前的区域,一般用来放出口、需要的操作
2.调用递归函数(需要确认传进去的参数)
3.调用递归函数后面的区域,这部分是等递归函数到出口之后才会去执行,所以在设计函数的时候默认上面的递归函数已经执行完毕,便于设计调用递归函数后面的区域(即默认上面是已知的)

posted @ 2025-03-14 23:50  Toby0919  阅读(1)  评论(0)    收藏  举报