程序调用自身的编程技巧称为递归( recursion)。一般来说,递归需要有边界条件、递归前进段和递归返回段。当边界条件不满足时,递归前进;当边界条件满足时,递归返回。
理论上,递归三要素可分为:

  1. 递归的终结点;
  2. 递归的公式;
  3. 递归的方向必须走向终结点;

    示例1:累加求和

    1. /**
    2. * 求 1 - n 的和
    3. */
    4. public static int f(int n){
    5. if(n == 1 ) {
    6. return 1;
    7. }
    8. return f(n - 1) + n;
    9. }
  4. 递归的终结点:f(1) = 1;

  5. 递归的公式:f(n) = f(n-1) + n;
  6. 递归的方向走向终结点 f(1);

    公式的转换

    对于公式 f(x) = f(x + 1) + 2 来说,其递归的方向为正无穷,当他的终结点为 f(1) 时,就需要转换公式来解决。

即:令 x = x - 1; 则 f(x) = f(x - 1) - 2;

示例2:n 的阶乘

  1. public static int f(int n){
  2. if(n == 1){
  3. return 1 ;
  4. }else{
  5. return f(n - 1) * n;
  6. }
  7. }
  1. 递归的终结点:f(1) = 1;
  2. 递归的公式
    1. n!= 123456(n-1)n
      f(n) = 123456(n-1)n
      f(n) = f(n-1)*n
  3. 递归的方向走向终结点 f(1);

    示例3:非规律化递归:啤酒问题


    啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶,问10元可以喝多少瓶,剩余多少盖子和瓶子 (15 3 1)

    1. /**
    2. * 啤酒2元1瓶,4个盖子可以换一瓶,2个空瓶可以换一瓶
    3. * @param money 多少钱
    4. * @param count 喝了多少瓶
    5. * @param gaizi 剩余盖子数
    6. * @param pingzi 剩余瓶子数
    7. * @return
    8. */
    9. public static int[] canDrink(int money,int count, int gaizi, int pingzi) {
    10. if (money > 1 || gaizi >= 4 || pingzi >= 2) {
    11. if (money > 0 && money != 1) {
    12. return canDrink(money - 2, ++count, ++gaizi, ++pingzi);
    13. }
    14. if (gaizi >= 4) {
    15. gaizi = gaizi - 4 + 1;
    16. return canDrink(money, ++count, gaizi, ++pingzi);
    17. }
    18. if (pingzi >= 2) {
    19. pingzi = pingzi - 2 + 1;
    20. return canDrink(money, ++count, ++gaizi, pingzi);
    21. }
    22. }
    23. return new int[]{count, gaizi, pingzi};
    24. }

    解法2:

    1. // 定义一个静态变量存储可以喝酒的总数
    2. public static int totalNum;
    3. public static int lastPingZiNum;
    4. public static int lastGaiZiNum;
    5. public static void buyBeer(int money){
    6. // a.拿钱买酒
    7. int number = money / 2 ;
    8. // 累加起来
    9. totalNum += number;
    10. // 算出当前剩余的全部盖子和瓶子数,换算成金额继续购买。
    11. int currentPingZiNum = lastPingZiNum + number ;
    12. int currentGaiZiNum = lastGaiZiNum + number ;
    13. // 把他们换算成金额
    14. int totalMoney = 0 ;
    15. totalMoney +=(currentPingZiNum/2)*2;
    16. //算出剩余的瓶子
    17. lastPingZiNum = currentPingZiNum % 2 ;
    18. // 换算盖子
    19. totalMoney+=(currentGaiZiNum / 4) * 2;
    20. lastGaiZiNum = currentGaiZiNum % 4 ;
    21. // 继续拿钱买酒
    22. if(totalMoney >= 2){
    23. buyBeer(totalMoney);
    24. }
    25. }