递归
递归在代码中的具体表现就是自己调用自己。
心法:在重复中找变化,在变化中找重复
目的:为了将一个大规模的问题分解成几个结构相似的小问题
功法:
1、找重复
- 找到一种划分方法,就原问题分解为直接量+小规模问题或分解为多个小规模问题(切蛋糕思维)
- 看能不能找到递推公式或等价代换
2、找变化 - 变化的量通常要作为参数
3、找出口 - 递归需要边界条件,否则会陷入死循环
1.累加
重复:f(n) = n+f(n-1)
变化:1-n之间被切的位置在变化
出口:n==1
static int sum(int n){
if(n == 1) return 1;
return n+sum(n-1);
}
2.用递归来打印
重复:打印i-j = 打印i +打印i+1 - j
变化: i-j之间被切的位置在变化
出口:i==j,只剩一个元素未被打印
static void prin(int i,int j){
if(i == j) {System.out.println(j);return;}
System.out.print(i+" ");
prin(i+1,j);
}
3.用递归来翻转字符串
重复:翻转length长度字符串 = 翻转length-1长度字符串 + 将最后一个字符串放到首位
变化: 0 - length之间被切的位置在变化
出口:length,只剩一个元素未被翻转,此位置就是它翻转后的位置
static String strRev(String str,int length){
if(str.length() == 1) return str.charAt(0)+"";
return str.charAt(length-1) + strRev(str.substring(0,length-1),length-1);
}
4.用递归来写插入排序
static void insertSort(int[] num,int i){
if(i == 0) return;
insertSort( num,i-1);
int m = num[i];
int j = i-1;
while(j>=0&&m<=num[j]){
num[j+1] = num[j];
j--;
}
num[j+1] = m;
}
5.汉诺塔问题
重复:将1-n个铁饼从A放到B,辅助C = 将1 - n-1个铁饼从A放到C+将第n个铁饼从A放到B+
将1 - n-1个铁饼从C放到B
变化: 起始位置,目标位置,辅助位置和要放的铁饼数量
出口:只剩下一个铁饼的情况
static void F(int n,String from,String to,String help){
if(n == 1) {
System.out.println("move"+n+"from " +from+"to"+to);
return;
}
F(n-1, from, help, to);
System.out.println("move"+(n)+"from " +from+"to"+to);
F(n-1,help,to,from);
}