递归——切蛋糕思维

切蛋糕思维

大致可以分为三部

  1. 找重复
    找到一种划分方法
    找递推公式或者等价转换
    都是父问题转化为求解子问题
  2. 找变化,变化的量通常作为参数
  3. 找边界:根据参数变化的趋势,对边界进行控制,适时终止递归

重复中的变化,变化中的重复!

1、数组累加

public class 递归_切蛋糕思维_数组累加 {
    static int f3(int[] arr,int begin){
        if(begin==arr.length-1 )
            return arr[begin];
        return arr[begin]+f3(arr,begin+1);
    }
    public static void main(String[] args){
        int res=f3(new int[]{1,2,3,4,5},0);
        System.out.println(res);
    }
}

在这里插入图片描述

2、翻转字符串

public class 递归_切蛋糕思维_翻转字符串 {
    public static void main(String[] args) {
        System.out.println(reverse("sasdasdas",8));
    }
    static String reverse(String res,int end){
        if (end==0)
            return ""+res.charAt(0);
        return res.charAt(end)+reverse(res,end-1);
    }
}

在这里插入图片描述
注意reverse中参数应该为字符串单个数量和-1

多分支遍历

3、斐波那契额数列

等价于两个子问题
1. 求第一项
2. 求第二项
3. 两项求和

public class 多分支遍历_斐波那契序列 {
    public static void main(String[] args) {
        System.out.println(fbnq(10));
    }
    static int fbnq(int n){
        if (n==1||n==2)
            return 1;
        return fbnq(n-1)+fbnq(n-2);
    }
}

在这里插入图片描述
4、最大公约数

public class 递推公式_最大公约数 {
    public static void main(String[] args) {
        System.out.println(f(27, 9));
    }

    static int f(int m, int n) {
        if (n == 0)
            return m;
        return f(n, m % n);
    }
}

在这里插入图片描述
4、插入排序

import java.util.Scanner;

public class 插入排序 {
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int[] a = new int[n];
        for (int i=0;i<n;i++){
            a[i]=sc.nextInt();
        }
        f(a, n);
    }
    static void f(int[] a, int k) {
        if (k == 0)
            return;
        f(a, k - 1);
        int x = a[k];
        int index = k - 1;
        while (x < a[index]) {
            a[index + 1] = a[index];
            index--;
        }
        a[index] = x;
    }
}

5、汉诺塔

1~N从A挪到B,C作为辅助
等价于:
1. 1~N-1从A挪到C,B作为辅助
2. 把N挪到B
3. 1~N-1从C挪到B,A作为辅助

public class 汉诺塔 {
    public static void main(String[] args) {
        printHaraiTower(3,"A","B","C");
    }
    static void printHaraiTower(int N,String from,String to,String help){
        if (N==1)
            System.out.println("move "+N+" from: "+from+" to: "+to);
        else {
            printHaraiTower(N-1,from,help,to);
            System.out.println("move "+N+" from: "+from+" to: "+to);
            printHaraiTower(N-1,help,to,from);
        }
    }
}

在这里插入图片描述
6、二分查找法
等价于三个子问题:

1. 左边找(递归)
2. 中间比
3. 右边找(递归)
左查找和右查找两者选其一


import java.util.Scanner;

public class 二分查找法 {
    public static void main(String[] args) {
        int[] n = new int[]{1, 2, 3, 4, 5};
        Scanner sc = new Scanner(System.in);
        int key = sc.nextInt();
        if (key < n[n.length - 1] && key > n[0])
            System.out.println(binarySearch(n, 1, 5, key));
        else
            System.out.println("关键值输入无效!");
    }

    public static int binarySearch(int[] arr, int low, int high, int key) {
        if (low > high)
            return -1;
        int mid = low + ((high - low) >> 1);
        int midVal = arr[mid];
        if (midVal < key)
            return binarySearch(arr, mid + 1, high, key);
        else if (midVal > key)
            return binarySearch(arr, low, high - 1, key);
        else
            return mid;
    }
}

在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值