递归-速记

递归

核心思想是 缩小范围(划分更小子问题)每一次递归会缩小子问题的范围在根据问题判断采用那种思路
  1. 切蛋糕型

    1. 单分支
    2. 公式型 (和数学有关 求出推导公式)
  2. 等价于型

切蛋糕试

单分支
分节成常数和一个小范围的问题 (划一刀思想)
阶乘
> 要求出一个数的阶乘 我们需要先取出第一个数 和后面的数相乘 这就将
我们要所求n的阶乘从 n 变成了 n-1 缩小了 n的范围
我们设定 函数 f(n)为求 n的阶乘 那么f(n-1)就是求n-1的阶乘 那马 n!= n*f(n-1)

public class 阶乘 {
    public static void main(String[] args) {
        int i = fun1(10);
        System.out.println(i);
    }
    static int fun1(int i){
        if (i==1){
            return 1;
        }
        return i*fun1(i-1);
    }
}

公式型
分解成多个小范围的子问题 (采用寻找递推公式 和等价代换)

    /**
     * 裴波那契序列  1 1 2 3 5 8 13
     *  符合 f(n)=f(n-1)+f(n-2)  (n>2)
    */
    public class 裴波那契序列 {
        public static void main(String[] args) {
            System.out.println(fun(7)); //13
        }
        static int  fun(int n){
            if (n==1||n==2){
                return 1;
            }
            return fun(n-1)+fun(n-2);
        }
    }
//辗转相除 用大叔除以小数 的到余数 余数为0则 最大公约数为 除数 若有余数 则 拿除数 在除以余数 直到 余数为 0 
public class 最大公约数 {
    public static void main(String[] args) {
        int fun = fun(10, 3);
        System.out.println(fun);
    }
    static int fun(int m,int n){
        if (n == 0){
            return m;
        }
        return fun(n,m%n);
    }
}

等价于型

将一个长度为 n 的数组排序 等价于 将一个 n-1 长度的数组排序 当 n-1 数组有序的时 将 第 n 个放到合适的位置
插入排序
public class 插入排序 {
    public static void main(String[] args) {
        int[] arr={1,3,2,6,3,4,7,9};
        fun(arr,1);
        System.out.println(Arrays.toString(arr));
    }

    static void fun(int[] arr,int k){
        if (k==arr.length-1){
            return;
        }
        int n=k;
        while (arr[n -1]>arr[n]&&n>=0){
            int temp=arr[n-1];
            arr[n-1]=arr[n];
            arr[n]=temp;
            n--;
        }
        fun(arr,k+1);
    }
}

习题

相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘(如下图)。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。操作规则:每次只能移动一个盘子,并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,操作过程中盘子可以置于A、B、C任一杆上。

做题之前先分析一下 当 盘子数为三的时候如何移到C 在接着看

分析完了我们再来考虑一下 这是一个什么问题 
首先 第1个盘子a->c
   第2个盘子a->b
   第1个盘子c->b  //这个时候我们发现 n-1个盘子都移动到了 辅助盘 A 另外两个盘相当于空(因为最后一个盘子最大 其他盘子都可以放上去 )
   
   第3个盘子a->c  将最大的 盘子移到到 C 
   
   第1个盘子b->a  //这里 发现 就是通过 A 将 B 中的盘子移到 C 
   第2个盘子b->c
   第1个盘子a->c
 于是我们总结   出一个规律就是 这个问题 是
  要 ** 盘子要移动的柱子 ** 上的n-1 个盘子 移动到一个**辅助的柱子**上
  再将 第 n 个盘子从要**盘子要移动的柱子**上移到的**最终的柱子**上  
  后将  ** 盘子要移动的柱子 ** 上的n-2 个盘子 移动到一个**辅助的柱子**上 
  再将 第 n-1 个盘子从要**盘子要移动的柱子**上移到的**最终的柱子**上 。。。。。。
  
  发现 其子问题相同 只不过是 柱子的编号不一样但性质是一样的  采用递归 在递归时交换参数  在分析  
     /**
       * 吧n个盘子从A移到 C
       *      等价于
       *          1,将 n-1 个盘子 通过 C 移到 B
       *          2,将 第 n个盘子移动到 从 A 移到到 C
       *          3,将 n-1的盘子从 B 通过 A 移到 C
      */
public class 汉罗塔 {
    public static void main(String[] args) {
        fun(3,'a','b','c');
    }

    /**
     * 把n个盘子从A移到 C
     *  将 n 个盘子移动到 C
     *      等价于
     *          1,将 n-1 个盘子 通过C 移到 B
     *          2,将 第 n个盘子移动到 从 A 移到到 C
     *          3,将 n-1的盘子从 B 通过 A 移到 C
    */
    static void fun(int n, char A,char B,char C){
        if (n==1){
            System.out.println("第"+n+"个盘子"+A+"->"+C);
            return;
        }
        fun(n-1,A,C,B);
        System.out.println("第"+n+"个盘子"+A+"->"+C);
        fun(n-1,B,A,C);
    }
}

urn;
}
fun(n-1,A,C,B);
System.out.println(“第”+n+“个盘子”+A+"->"+C);
fun(n-1,B,A,C);
}
}


递归 在传递参数的时候不要使用 ++等 因为有时候递归会回过来在执行之前没执行玩的语句 使用++会导致这一层的变量值发生变化
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值