动态规划:爬楼梯及三种变形

动态规划:爬楼梯

文章目录

  • 动态规划:爬楼梯
    • 一、[70. 爬楼梯](https://leetcode-cn.com/problems/climbing-stairs/)
      • 1.1 解法一:递归
      • 1.2 解法三:递归+记忆化搜索
      • 1.3 动态规划
    • 二、如果一次可以上1、2、3步,有多少种方法
    • 三、如果每次可以上1、2、3阶台阶,并且相邻的步伐不能相同,有多少种方法
    • 四、[746. 使用最小花费爬楼梯](https://leetcode-cn.com/problems/min-cost-climbing-stairs/)
      • 4.1 动态规划
      • 4.2 动态规划:空间优化

一、70. 爬楼梯

1.1 解法一:递归

0, 1, 2, 3, 5, 8, 13, 21, 34, 55…

    /**
     * 递归
     * @param n
     * @return
     */
    public static int solve01(int n) {
        if (n<=2) return n;
        return solve01(n-1) + solve01(n-2);
    }

1.2 解法三:递归+记忆化搜索

    /**
     * 递归+记忆化搜索
     * @param n
     * @return
     */
    public static int solve02(int n) {
        int[] a = new int[n+1];
        return solve02(n, a);
    }

    private static int solve02(int n, int[] a) {
        if (n<=2) return n;
        if (a[n]!=0) return a[n];
        a[n] = solve02(n-1, a) + solve02(n-2, a);
        return a[n];
    }

1.3 动态规划

    /**
     * 动态递推
     * @param n
     * @return
     */
    public static int solve03(int n) {
        if (n<=2) return n;
        int x=1, y=2, res=0;
        for (int i=3; i<=n; i++) {
            res = x + y;
            x = y;
            y = res;
        }
        return res;
    }

二、如果一次可以上1、2、3步,有多少种方法

    /**
     * 爬楼梯: 一次可以上 1、2、3 阶台阶
     * @param n
     * @return
     */
    public static int solve(int n) {
        if (n<=2) return n;
        if (n==3) return 4;
        int x = 1, y = 2, z = 4, res = 0;
        for (int i=4; i<=n; i++) {
            res = x + y + z;
            x = y;
            y = z;
            z = res;
        }
        return res;
    }

三、如果每次可以上1、2、3阶台阶,并且相邻的步伐不能相同,有多少种方法

    /**
     * 走n阶台阶: 一次可以走 1、2、3 步,相邻步数不能相同
     * @param n
     * @return
     */
    public static int solve(int n) {
        if (n<=2) return n;
        if (n==3) return 2;
        // 走n阶台阶,第一步可以走1、2、3
        int[][] dp = new int[n+1][4];
        // n=1 时,第一步只能走 1步
        dp[1][1] = 1;
        // n=2 时, 第一步只能走 1步
        dp[2][2] = 1;
        // n=3 时,第一步可以走 1 步、2步
        dp[3][1] = 1;
        dp[3][2] = 1;
        dp[3][3] = 1;

        for (int i=4; i<=n; i++) {
            // 走i步:第一步走1步=第二步走2步+第二步走3步
            dp[i][1] = dp[i-1][2] + dp[i-1][3];
            // 走i步:第一步走2步=第二步走1步+第二步走3步
            dp[i][2] = dp[i-2][1] + dp[i-2][3];
            // 走i步:第一步走3步=第二步走1步+第二步走2步
            dp[i][3] = dp[i-3][1] + dp[i-3][2];
        }
        // 上n阶台阶 = 第一步走1步 + 第一步走2步 + 第一步走3步
        return dp[n][1] + dp[n][2] + dp[n][3];
    }

四、746. 使用最小花费爬楼梯

4.1 动态规划

    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        if (n<2)return 0;
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 0;
        for (int i=2; i<=n; i++) {
            dp[i] = Math.min(dp[i-1]+cost[i-1], dp[i-2]+cost[i-2]);
        }
        return dp[n];
    }

4.2 动态规划:空间优化

    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int pre = 0;
        int cur = 0;
        for (int i=2;i<=n; i++) {
            int t = cur;
            cur = Math.min(cur + cost[i-1] , pre + cost[i-2]);
            pre = t;
        }
        return cur;
    }

你可能感兴趣的:(算法,动态规划)