递归设计经验
– 找重复(子问题)
– 找重复中的变化量->(参数)
– 找参数变化趋势-> 设计出口
练习策略
– 循环改递归
– 经典递归
– 大量练习,总结规律,掌握套路
– 找到感觉,挑战高难度
基础练习
- 求阶乘 f(n)=n*f(n-1)
- 打印i-j p(i,j)=p(i)->p(i+1,j)
f2(int i,int j){
if(i>j)
return ;
System.out.println(i);
f2(i+1,j);
}
- 数组求和
f3(int[] arr,int begin){
if(begin==arr.length-1){
return arr[begin];
}
return arr[begin]+f3(arr,begin+1);
}
- 翻转字符串
String reverse(String src,int end){
if(end==0){
return ""+src.charAt(0);
}
return src.charAt(end)+reverse(src,end-1);
}
— 1、切蛋糕思维—
- 费波纳茨数列 f(n)=f(n-1)+f(n-2)
- 最大公约数 f(m,n)=f(n,m%n)
— 2、切不开,有没有递推公式?有没有等价转换?—
- 插入排序改递归
void insertSort(int[] arr,int k){
if(k==0){
return ;
}
//对前k-1个元素排序
insertSort(arr,k-1);
//把位置k的元素插入到前面部分
int x=arr[k];
int index=k-1;
while(x<arr[index]){
arr[index+1]=arr[index];
index--;
}
arr[index]=x;
}
- 汉诺塔
思路:
1-N从A移动到B,C作为辅助
等价于:- 1、1~N-1从A移动到C,B为辅助
- 2、把N从A移动到B
- 3、1-N-1从C移动到B,A为辅助
void printHanoiTower(int N,String from,String to ,String help){
if(N==1){
System.out.println("move "+N+" from "+from+" to "+to);
return;
}
printHanoiTower(N-1,from,help,to);//先把前N-1个盘子挪到辅助空间上去
System.out.println("move "+N+" from "+from+" to "+to);//N可以顺利到达target
printHanoiTower(N-1,help,to,from);//让N-1从辅助空间回到源空间上去
}
全范围内二分查找
- 等价于三个子问题
- 左边找(递归)
- 中间比
- 右边找(递归)
注意:左查找和右查找只选其一
小结
找重复
- 1、找到一种划分方法
- 2、找到递推公式或者等价转换
都是父问题转化为求解子问题
找变化的量
- 变化的量通常要作为参数
找出出口
- 根据参数变化的趋势,对边界进行控制,适时终止递归