2.1-2.5 递归与排序解法

一、递归

递归设计经验

  • 找重复(子问题)
  • 找重复中变化量→参数
  • 找参数变化趋势→设计边界

练习策略

  • 循环改递归
  • 经典递归
  • 大量练习,总结规律,掌握套路
  • 找到感觉,挑战高难度

二、递归求解

单分支递归 

  1.使用递归求阶乘

public static int f(int n){
    if(n==1){
        return 1;
    }
    return f*f(n-1);
}
  •    找重复:n*(n-1)的阶乘,求n-1的阶乘是原问题的重复(规模更小)
  •    找变化:变化的量应该作为参数
  •    找边界:出口

  2.打印i-j

public static void printItoJ(int i,int j){
    if(i>j){
        return;
    }
    System.out.println(i);
    printItoJ(i+1,j);
}
  • 找重复:打印i,然后再打印[i+1,j],规模更小
  • 找变化:变化的量应该作为参数
  • 找边界:出口

  3.数组求和

public static int sum(int[] nums,int i){
    if(i==nums.length){
        return 0;
    }
    return nums[i]+sum(nums,i+1);
}

  4.翻转字符串

public static String reverse(String str,int index){
    if(index==0){
        return String.valueOf(str.charAt(0));
    }
    return String.valueOf(str.charAt(index))+reverse(str,index-1);
}

 5.递归求最大公约数(碾转相除法)

public static int gcd(int a,int b){
    if(a%b==0){
        return b;
    }
    return gcd(b,a%b);
}
  •  递推公式

  6.递归来进行插入排序

  • 非递归插入排序
public static void insertionSort(int[] nums){
    for(int i = 1;i<nums.length;i++){
        int temp = nums[i];
        int j = i-1;
        while(j>=0 && temp<nums[j]){
            nums[j+1] = nums[j];
            j--;
        }
        nums[j+1] = temp;
    }
}
  • 递归插入排序
public static void insertionSort(int[] nums,int index){
    if(index==0){
        return;
    }
    //对前面的数进行排序
    insertionSort(nums,index-1);
    //将当前数插入有序数组中
    int temp = nums[index];
    int j = index-1;
    while(j>=0 && temp<nums[j]){
        nums[j+1] = nums[j];
        j--;
    }
    nums[j+1] = temp;
}

多分支递归 

  1.求斐波那契数列第N项

public static int f(int n){
    if(n==1 || n==2){
        return 1;
    }
    return f(n-1)+f(n-2);
}
  •   递推公式f(n)=f(n-1)+f(n-2)

  其实是先根(先序)遍历递归解答树,如下图所示:

  

  发现有很多重复项,可以优化(以后讲)

递归总结: 

找重复

  • 找到一种划分方法
  • 如果找不到一种划分方法,找到递推公式或者一种等价转化(往往是数学上的)

找变化的量

  • 变化的量通常要作为参数

找到出口

  • 根据参数变化的趋势,对边界进行处理控制,适时终止递归
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值