力扣labuladong一刷day71天动态规划5题

力扣labuladong一刷day71天动态规划

文章目录

      • 力扣labuladong一刷day71天动态规划
      • 动态规划五部曲
      • 一、509. 斐波那契数
      • 二、70. 爬楼梯
      • 三、746. 使用最小花费爬楼梯
      • 四、62.不同路径
      • 五、63. 不同路径 II

动态规划五部曲

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

一、509. 斐波那契数

题目链接:https://leetcode.cn/problems/fibonacci-number/description/
思路:经典题目,递推公式题目都给出了,f(n) = f(n-1)+f(n-2),为了避免重复计算,我们使用a和b记录f(n-1)和f(n-2),充当记事本。

class Solution {
    public int fib(int n) {
        if(n < 2) return n;
        int a = 0, b = 1, c = 0;
        for (int i = 2; i <= n; i++) {
            c = a+b;
            a = b;
            b = c;
        }
        return c;
    }
}

二、70. 爬楼梯

题目链接:https://leetcode.cn/problems/climbing-stairs/description/
思路:定义dp[i]表示爬到第i个楼梯,有dp[i]种方法,因为一次只能爬1或者2个台阶,那么要想抵达dp[i]就要么从dp[i-1]要么从dp[i-2]出发,从dp[i-1]只需要一次走一个台阶即可,从dp[i-2]只需要一次走2个台阶即可,dp[i-2]不能连续走两个1这样会和dp[i-1]重复,故递推公式为dp[i]=dp[i-1]+dp[i-2]。

class Solution {
    public int climbStairs(int n) {
        if (n < 3) return n;
        int a = 1, b = 2, c = 0;
        for (int i = 3; i <= n; i++) {
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }
}

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

题目链接:https://leetcode.cn/problems/min-cost-climbing-stairs/description/
思路:这题和前面的也类似,知道递推公式就能做题,dp[i] = Math.min(dp[i-1], dp[i-2])。

class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int len = cost.length;
        for (int i = 2; i < cost.length; i++) {
            cost[i] += Math.min(cost[i-1], cost[i-2]);
        }
        return Math.min(cost[len-1], cost[len-2]);
    }
}

四、62.不同路径

题目链接:https://leetcode.cn/problems/unique-paths/description/
思路:每一个位置可以从它的上方和左边走来,那么定义dp[i][j]表示达到m=i,n=j这个位置有dp[i][j]种不同的路径,递推公式为dp[i][j]=dp[i][j-1]+dp[i-1][j]。现在使用的是二维备忘录,还是可以简化为一维的,dp[i][j-1]即为dp[j],故,dp[j]=dp[j]+dp[j-1],初始化dp[0]=1,而且内层遍历从1开始。

class Solution {
    public int uniquePaths(int m, int n) {
        int[] dp = new int[n];
        dp[0] = 1;
        for (int i = 0; i < m; i++) {
            for (int j = 1; j < n; j++) {
                dp[j] += dp[j-1];
            }
        }
        return dp[n-1];
    }
}

五、63. 不同路径 II

题目链接:https://leetcode.cn/problems/unique-paths-ii/description/
思路:和上一题类似,只不过多了障碍物,处理步骤是一样的。

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        if (obstacleGrid[0][0] == 1) return 0;
        int x = obstacleGrid.length, y = obstacleGrid[0].length;
        int[] dp = new int[y];
        for (int i = 0; i < y; i++) {
            if (obstacleGrid[0][i] == 1) break;
            dp[i] = 1;
        }
        for (int i = 1; i < x; i++) {
            for (int j = 0; j < y; j++) {
                if (obstacleGrid[i][j] == 1) {
                    dp[j] = 0;
                } else if (j != 0) {
                    dp[j] += dp[j-1];
                }
            }
        }
        return dp[y-1];
    }
}

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