递归

递归

暴力递归:

  1. 把问题转化为规模缩小了的同类问题的子问题
  2. 有明确的不需要继续进行递归的条件(base case)
  3. 有当得了子问题得结果之后得决策过程4,不记录每一个子问题得解
1.求n!
    /*
    * 求n!
    * */
    public static long getFactorial1(int n){
        if (n == 1){
            return 1L;
        }
        return (long) n * getFactorial1(n - 1);
    }

    /*
    * 非递归求n!
    * */
    public static long getFactorial2(int n){
        long result = 1L;
        for (int i = 1; i <= n; i++){
            result *= i;
        }
        return result;
    }
2.汉诺塔

在这里插入图片描述

    /*
    * 汉诺塔
    * from to help
    * 1) 1-(n-1) from -> help
    * 2) n from -> to
    * 3) 1-(n-1) help -> to
    * */
    public static void Hanoi(int N, String from, String to, String help){
        if(N == 1){
            System.out.println("Move 1 from " + from + " to " + to);
        } else {
            Hanoi(N - 1, from, help, to);
            System.out.println("Move " + N + " from " + from + " to " + to);
            Hanoi(N - 1, help, to, from);
        }
    }

    /*
     * 1) 1-(n-1) left -> mid
     * 2) n left -> right
     * 3) 1-(n-1) mid -> right
     * */
    public static void moveLeftToRight(int N){
        if(N == 1){
            System.out.println("move 1 from left to right");
        } else {
            moveLeftToMid(N - 1);
            System.out.println("move " + N + " from left to right");
            moveMidToRight(N - 1);
        }
    }

    /*
    * 1) 1-(n-1) left -> right
    * 2) n left -> mid
    * 3) 1-(n-1) right -> mid
    * */
    public static void moveLeftToMid(int N){
        if(N == 1){
            System.out.println("move 1 from left to mid");
        } else {
            moveLeftToRight(N - 1);
            System.out.println("move " + N + " from left to mid");
            moveRightToMid(N - 1);
        }
    }

    /*
     * 1) 1-(n-1) right -> left
     * 2) n right -> mid
     * 3) 1-(n-1) left -> mid
     * */
    public static void moveRightToMid(int N){
        if(N == 1){
            System.out.println("move 1 from right to mid");
        } else {
            moveRightToLeft(N - 1);
            System.out.println("move " + N + " from right to mid");
            moveLeftToMid(N - 1);
        }
    }

    /*
     * 1) 1-(n-1) mid -> left
     * 2) n mid -> right
     * 3) 1-(n-1) left -> right
     * */
    public static void moveMidToRight(int N){
        if(N == 1){
            System.out.println("move 1 from mid to right");
        } else {
            moveMidToLeft(N - 1);
            System.out.println("move " + N + " from mid to right");
            moveLeftToRight(N - 1);
        }
    }

    /*
     * 1) 1-(n-1) mid -> right
     * 2) n mid -> left
     * 3) 1-(n-1) left -> right
     * */
    public static void moveMidToLeft(int N){
        if(N == 1){
            System.out.println("move 1 from mid to left");
        } else {
            moveMidToRight(N - 1);
            System.out.println("move " + N + " from mid to left");
            moveLeftToRight(N - 1);
        }
    }

    /*
     * 1) 1-(n-1) right -> mid
     * 2) n right -> left
     * 3) 1-(n-1) left -> mid
     * */
    public static void moveRightToLeft(int N){
        if(N == 1){
            System.out.println("move 1 from right to left");
        } else {
            moveRightToMid(N - 1);
            System.out.println("move " + N + " from right to left");
            moveLeftToMid(N - 1);
        }
    }

Hanoi输出

move 1 from left to right
move 2 from left to mid
move 1 from right to mid
move 3 from left to right
move 1 from mid to left
move 2 from mid to right
move 1 from left to right
3. 子序列

在这里插入图片描述

    /*
    * 打印一个字符串得全部子序列,包括空字符串
    * str = "abc"
    * subsequence = ["abc", "ab", "ac", "a", "bc", "b", "c", ""]
    * */
    public static void printAllSubsequence(char[] str, int i, String res){
        if(i == str.length){
            System.out.println(res);
            return;
        }
        //不要当前字符
        printAllSubsequence(str, i + 1, res);
        //要当前字符
        printAllSubsequence(str, i + 1, String.valueOf(str[i]));
    }

输出


c
b
bc
a
ac
ab
abc
4. 打印字符串全排列

打印一个字符串得全排列
在这里插入图片描述

    public static void printAllPermutations1(String str){
        char[] chs = str.toCharArray();
        process1(chs, 0);
    }

    public static void process1(char[] chs, int i){
        //base case
        if(i == chs.length){
            System.out.println(String.valueOf(chs));
        }
        for (int j = i; j < chs.length; j++){
            //i位置和j位置的字符交换
            swap(chs, j, i);
            //跑剩下位置的字符
            process1(chs, i + 1);
        }
    }

    public static void swap(char[] chs, int j, int i){
        char tmp = chs[j];
        chs[j] = chs[i];
        chs[i] = tmp;
    }

打印一个字符串的全部排列,要求不要出现重复的排列

    public static void printAllPermutations2(String str){
        char[] chs = str.toCharArray();
        process2(chs, 0);
    }

    public static void process2(char[] chs, int i){
        if(i == chs.length){
            System.out.println(String.valueOf(chs));
        }
        HashSet<Character> set = new HashSet<>();
        for (int j = i; j < chs.length; j++){
            if(!set.contains(chs[j])){
                set.add(chs[j]);
                swap(chs, i, j);
                process2(chs, i + 1);
            }
        }
    }

输出结果

abc
acb
cab
cba
abc
acb
======
abc
acb
cab
cba
======
acc
acc
cac
cca
acc
acc
======
acc
cac
cca
======
5. 母牛生牛

母牛每年生一只母牛,新出生的母牛成长三年后也能每年生一只母牛,假设不会死。求N年后,母牛的数量。
在这里插入图片描述

    public static int cow(int year){
        if(year < 1){
            return 0;
        }
        if(year == 1 || year == 2 || year == 3){
            return year;
        }
        return cow(year - 1) + cow(year - 3);
    }

如果每只母牛只能活10年,求N年后,母牛的数量。
F(N) = F(N - 1)+F(N - 3)-F(N - 10)

    public static int cow2(int year){
        if(year < 1){
            return 0;
        }
        if(year == 1 || year == 2 || year == 3){
            return year;
        }
        if(year < 10)
            return cow(year - 1) + cow(year - 3);

        return cow(year - 1) + cow(year - 3) - cow(year - 10);
    }
6. 逆序栈

给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数。如何实现

	public static void reverse(Stack<Integer> stack){
        if(stack.isEmpty())
            return;
        int i = getAndRemoveLastElement(stack);
        reverse(stack);
        stack.push(i);
    }

    //得到并返回栈底元素
    public static int getAndRemoveLastElement(Stack<Integer> stack){
        int result = stack.pop();
        if(stack.isEmpty()){
            return result;
        }else {
            int last = getAndRemoveLastElement(stack);
            stack.push(result);
            return last;
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值