算法学习--递归

递归

1.递归的设计经验

  1. 找重复(子问题)
  2. 找重复中的变化量(参数)
  3. 找参数的变化趋势
  4. 找出边界(递归结束的条件)

2.典型的例题

  1. 求阶乘
public static int fn(int n){
    if(n == 1){ //递归的边界
        return 1;
    }
    return n * fn(n-1); //递归中重复的地方
}
  1. 用递归打印i~j的所有数
public static void printij(int i, int j){
    System.out.println(i);
    if(i < j) {
        printij(i + 1, j);
    }
}
  1. 用递归实现数组求和
public static int sum(int[] arr){
    return sum(arr, arr.length-1);
}

private static int sum(int[] arr, int n){
    if(n == 0){
        return arr[n];
    }
    //当前的结果为前一个结果加当前元素的值
    return sum(arr, n-1) + arr[n];
}
  1. 反转字符串
public static String reverse(String s){
    return reverse(s, s.length()-1);
}

private static String reverse(String s, int n){
    if(n == 0){
        return "" + s.charAt(0);
    }
    return s.charAt(n) + reverse(s, n-1);
}
  1. 斐波那契数列
public static int fib(int n){
    if(n == 1 || n ==2) return 1;
    return fib(n-1) + fib(n-2);
}
  1. 求最大公约数
public static int gcd(int m, int n){
    if(m % n == 0){
        return n;
    }
    return gcd(n, m%n);
}
  1. 插入排序递归实现
public static void insertSort(int[] arr){
    insertSort(arr, arr.length-1);
}

private static void insertSort(int[] arr, int k){
    if(k == 0) return;
    insertSort(arr, k-1);
    int i = k-1;
    int x = arr[k];
    while (i > 0 && arr[i] > x){
        arr[i+1] = arr[i];
        i--;
    }
    arr[i+1] = x;
}
  1. 二分查找的递归实现
public static void binarySerach(int[] arr, int num){
    Serach(arr, 0, arr.length-1, num);
}
private static void Serach(int[] arr, int low, int high, int num){
    //递归必须要有结束的条件
    if(low > high){
        System.out.println("数列中没有该值!");
        return;
    }
    int mid = (low+high)/2;
    int midVal = arr[mid];
    if(num > midVal){
        Serach(arr, mid+1, high, num);
    }else if(num < midVal){
        Serach(arr, low, mid-1, num);
    }else{
        System.out.println("找到" + num + ",在第" + (mid+1) + "位!");
    }
}
  1. 汉诺塔问题
public static void hanoiTower(int n){
    hanoiTower(n, 'A', 'B', 'C');
}

private static void hanoiTower(int n, char a, char b, char c){
    if(n == 1){
        System.out.println("第1个盘子:" + a + "->" + c);
    }else {
   	    //把前n-1个盘子从a移动到b上
        hanoiTower(n - 1, a, c, b); 
        //把第n个盘子(最大的)从a移动到c
        System.out.println("第" + n + "个盘子:" + a + "->" + c);
        //把b上的n-1个盘子从b移动到c 
        hanoiTower(n - 1, b, c, a); 
    }
}
  1. 上台阶进阶版,一次可以跳1-n阶
/*
一只青蛙一次可以跳上1级台阶,也可以跳上2级……它也可以跳上n级。
求该青蛙跳上一个n级的台阶总共有多少种跳法。
由上一题可知,一次最多可以跳2阶时 f(n) = f(n-1) + f(n-2)
根据推导,一次可以跳3阶时,f(n) = f(n-1) + f(n-2) + f(n-3)
可以得出,一次可以跳n阶时,f(n) = f(n-1) + f(n-2) + ... + f(n-n) = f(0) + f(1) + ... + f(n-1)
再还有,一次可以跳n-1阶时,f(n-1) = f(0) + f(1) + ... + f(n-2)
    f(n)   = f(0) + f(1) + ... + f(n-2) + f(n-1)
  - f(n-1) = f(0) + f(1) + ... + f(n-2)
---------------------------------------------
f(n) - f(n-1) = f(n-1) --> f(n) = 2*f(n-1);
*/
public static int JFII(int target){
    if(target == 0) return 0;
    if(target == 1) return 1;
    return 2*JumpFloorII(target-1);
}
//非递归实现
public static int JumpFloorII(int target) {
    if(target == 0) return 0;
    if(target == 1) return 1;
    int a = 1;
    while (target > 1){
        a = 2*a;
        target--;
    }
    return a;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值