左神第八课之递归算法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/BuZiShuoquoto/article/details/81179322

题目一
求n!

简单得不想说

题目二

汉诺塔问题
古代有一个梵塔,塔内有三个座A、B、C,A座上有64个盘子,盘子大小不等,大的在下,小的在上(如图)。有一个和尚想把这64个盘子从A座移到C座,但每次只能允许移动一个盘子,并且在移动过程中,3个座上的盘子始终保持大盘在下,小盘在上。在移动过程中可以利用B座,要求输出移动的步骤 。
这里写图片描述

解答

把A上的盘子编号1,2,3,4(最大的),现在把4移到C只要1,2,3到B再把4移动到C,在把1,2,3移动到C


当搬运的碟子数n=1时,直接搬运即可;当n>1时,要把n个碟子从针1搬运到针3,则必须通过针2(即需要一个独立于源针和目的针的中间针,用来辅助);假设我们已经成功的把上面较小的n-1个碟子搬运到了针2,那么我们只需要再把第n个碟子(底层最大的那个)搬运到针3,再把针2的n-1个碟子搬运到针3,那么这n个碟子塔就成功的搬运到了针3了.而整个n-1的塔要怎么搬运呢?这就是递归啦
所以整个步骤:
1.搬运n-1个碟子到中间针(递归)
2.搬运第n个碟子到目的针
3.搬运中间针的n-1个碟子到目的针(递归)
void move (getone,putone)
函数的作用是用于搬运最底层的第n个碟子,从getone针搬到putone针
void hanoi (n,one,two,three)
函数的作用是,把n层塔从one针(源)搬运到three针(目的),用two针来辅助(中间)
所以上面的步骤就可以翻译成c语言了
要想把n个碟子从one针搬运到three针的三个步骤:
(与第一段陈述的三个步骤对应,即hanoi(n,one,two,three)函数要完成的功能,函数主体)
1.hanoi(n-1,one,three,two);是递归调用,如果n-1>1则它又会去执行3个步骤,以至于无穷
2.move(one,three);这一步是具体移动,所以要输出移动方法,让用户能看见移动方向
3.hanoi(n-1,two,one,three);递归
递归调用只要有整体观念就行了,你在写代码的过程中可以把”移动n-1个塔”看作一步完成的,至于这步是怎么完成的,会由计算机逐级递归展开函数栈具体实现,我们不必多想.因为每一级的过程都是一样的,所以用递归,减少代码规模
递归的思想相对较容易,即只看见本层次,低层次由于过程和本层完全相同,调用递归函数自身,来重复利用代码.由于会函数嵌套调用会有多余的时间空间耗费,所以在递归次数过大等情况下,尽量用非递归的方法实现.

代码如下

public class Code_02_Hanoi {
    static int b=0;
    public static void hanoi(int n,String from, String help, String to) {
        if (n ==1) {
            System.out.printf("%d号盘:%s-->%s\n",n,from,to);
            b++;
        }else{
        hanoi(n-1,  from, to, help);
        System.out.printf("%d号盘:%s-->%s\n",n ,from,to);
        hanoi(n-1,  help, from, to);
        b++;
        }
    }
    public static void main(String[] args) {
        int n = 4;
        hanoi(n,  "A", "B", "C");
        System.out.println(b);
    }

}

题目四

打印一个字符串的全部排列

import java.util.LinkedList;
import java.util.List;

public class Code_03_Print_All_Subsquences {
    public static List<List<Character>> ans = new LinkedList<List<Character>>();
    public static LinkedList<Character> list = new LinkedList<Character>();

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

    private static void process(char[] chs, int index) {
        if (index >= chs.length ) {
            LinkedList<Character> list2 = new LinkedList<Character>();
            list2.addAll(list);
            ans.add(list2);
            return;
        }
        list.add(chs[index]);
        process(chs, index + 1);
        list.pollLast();
        process(chs, index + 1);
    }
    public static void main(String[] args) {
        printAllSubsquence("123");
        System.out.println(ans);
    }
}

题目五

打印一个数字的全排列

package lesson8;

import java.util.LinkedList;
import java.util.List;

public class Code_04_Print_All_Permutations {

    public static List<List<Integer>> ans = new LinkedList<List<Integer>>();
    public static boolean[] v = new boolean[100];
    public static LinkedList<Integer> list = new LinkedList<Integer>();

    public static void robot(int index, int[] nums) {
        if (index >= nums.length) {
            List<Integer> list2 = new LinkedList<Integer>();
            list2.addAll(list);
            ans.add(list2);
            return;
        }
        for (int i = 0; i < nums.length; i++) {
            if (v[i] == false) {
                v[i] = true;
                list.add(nums[i]);
                robot(index + 1, nums);
                list.pollLast();
                v[i] = false;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = { 1, 2, 3 };
        robot(0, arr);
        System.out.println(ans);
    }

}

题目六

母牛每年生一只母牛,新出生的母牛成长三年后也能每年生一只母牛,假设不会死。求N年后,母牛的数量。

public class Code_05_Cow {

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

    public static int cowNumber2(int n) {
        if (n < 1) {
            return 0;
        }
        if (n == 1 || n == 2 || n == 3) {
            return n;
        }
        int res = 3;
        int pre = 2;
        int prepre = 1;
        int tmp1 = 0;
        int tmp2 = 0;
        for (int i = 4; i <= n; i++) {
            tmp1 = res;
            tmp2 = pre;
            res = res + prepre;
            pre = tmp1;
            prepre = tmp2;
        }
        return res;
    }

    public static void main(String[] args) {
        int n = 20;
        System.out.println(cowNumber1(n));
        System.out.println(cowNumber2(n));
    }

}

题目七

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

import java.util.Stack;

public class Code_06_ReverseStackUsingRecursive {

    public static int process(Stack<Integer> s) {
        int a = s.pop();
        if (s.isEmpty()) {
            return a;
        }
        int b = process(s);
        s.push(a);
        return b;
    }

    public static void reverse(Stack<Integer> s, int n, int size) {
        if (n == size) {
            return;
        }
        int a = process(s);
        reverse(s, n + 1, size);
        s.push(a);
    }

    public static void main(String[] args) {
        Stack<Integer> test = new Stack<Integer>();
        test.push(1);
        test.push(2);
        test.push(3);
        test.push(4);
        test.push(5);
        reverse(test, 0, test.size());
        System.out.println(test);
    }
}

题目八

给你一个二维数组,二维数组中的每个数都是正数,要求从左上角走到右下角,每一步只能向右或者向下。沿途经过的数字要累加起来。返回最小的路径和。

解答
动态规划

题目九

给你一个数组arr,和一个整数aim。如果可以任意选择arr中的数字,能不能累加得到aim,返回true或者false

题目十

给定两个数组w和v,两个数组长度相等,w[i]表示第i件商品的重量,v[i]表示第i件商品的价值。 再给定一个整数bag,要求你挑选商品的重量加起来一定不能超 过bag,返回满足这个条件下,你能获得的最大价值。

猜你喜欢

转载自blog.csdn.net/BuZiShuoquoto/article/details/81179322