暴力递归
一、暴力递归
暴力递归就是尝试
1,把问题转化为规模缩小了的同类问题的子问题
2,有明确的不需要继续进行递归的条件(base case)
3,有当得到了子问题的结果之后的决策过程
4,不记录每一个子问题的解
- 回溯-表示大问题被拆解为小问题,小问题返回给大问题信息,就是回溯
- 分治:大问题被拆解成小的子问题,就是分治
二、汉诺塔问题
打印n层汉诺塔从最左边移动到最右边的全部过程
这道题的我们首先明白汉诺塔圆盘移动,如果杆子上没有圆盘,可以移动到该杆,如果有圆盘则必须移动比该圆盘小的圆盘到该圆盘上,即只能小压大。
-
思路一:
1)先把1到N-1层的圆盘移到中间的杆上;
2)再把N层的圆盘移到最右边的杆子上;
3)最后把1到N-1上的圆盘从中间杆子移到右侧,结束。 -
思路二:抽象一下,别去考虑左中右,理解成从from移到to,from和to都可能是左中右其中的一个。所以定义from、to、other这三个杆子,
1)把1到N-1从from移到other;
2)把N层从from移到to;
3)把1到N-1层从other移到ti上,结束。
public class hannuoTa {
//思路一:
public static void hanoil(int n){
leftToRight(n);
}
public static void leftToRight(int n){
if (n == 1){
System.out.println("move 1 from left to right");
return;
}
leftToMid(n-1); //左边的N-1移到中间
System.out.println("move"+n+"from left to right");//再把N层的圆盘移动到最右侧的杆上
midToRight(n-1);//把1到N-1个圆盘从中间杆移动到最右侧
}
private static void leftToMid(int i) {
if (i == 1){
System.out.println("move 1 from left to mid");
return;
}
leftToRight(i-1);
System.out.println("move"+i+"from left to mid");
rightToMid(i-1);
}
private static void rightToMid(int i) {
if (i == 1){
System.out.println("move 1 from right to mid");
return;
}
rightToLeft(i-1);
System.out.println("move"+i+"from right to mid");
leftToMid(i-1);
}
private static void midToRight(int i) {
if (i == 1){
System.out.println("move 1 from mid to right");
return;
}
midToLeft(i-1);
System.out.println("move"+i+"from mid to right");
leftToRight(i-1);
}
private static void midToLeft(int i) {
if (i ==1){
System.out.println("move 1 from mid to left");
return;
}
midToRight(i-1);
System.out.println("move"+i+"from mid to left");
rightToLeft(i-1);
}
private static void rightToLeft(int i) {
if (i == 1){
System.out.println("move 1 from right to left");
return;
}
rightToMid(i-1);
System.out.println("move"+i+"from right to left");
midToLeft(i-1);
}
//思路二 暴力递归
public static void process(int N, String from, String to, String other){
if (N == 1){
System.out.println("move 1 from" + from + "to" + to);
}else {
process(N-1, from,other,to);
System.out.println("move"+N+"from"+from+"to"+to);
process(N-1,other,to,from);
}
}
public static void hanoi2(int n) {
if (n > 0) {
process(n, "left", "right", "mid");
}
}
public static void main(String[] args) {
int N = 3;
hanoil(N);
System.out.println("=====");
hanoi2(N);
}
}
三、打印一个字符串的全部子序列,包括空字符串(去重+不去重)
- 先分清楚两个概念:子串和子序列
- 子串:必须是连续的,用for循环可以做
- 子序列:比子串自由,可以不连续
这道题的思路,暴力递归,每来