Day39 动态规划 LeetCode 62 63

39 阅读1分钟

62. 不同路径

心得

  • 按照步骤即可AC

题解

  • 可以优化空间从O(M*N)到O(M),即利用一个数组保存上一次状态行的值,然后本次叠加之前的状态和数组,数组用过之后之前的位置即空置出来
  • 重点掌握方法一
// 时间(M*N) 空间(M*N)
class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> dp(m, vector<int>(n)); // 1.dp[i][j] 表示到达i行j列的不同路径
        for (int i = 0; i < m; i++) { // 3.第一列初始化
            dp[i][0] = 1;
        }
        for (int j = 0; j < n; j++) { // 3.第一行初始化
            dp[0][j] = 1;
        }
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) { // 4.遍历
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; // 2.递推公式
            }
        }
        return dp[m-1][n-1];
    }
};
// 优化空间
class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<int> dp(n);
        for (int i = 0; i < n; i++) {
            dp[i] = 1;
        }
        for (int j = 1; j < m; j++) {
            for (int i = 1; i < n; i++) {
                dp[i] += dp[i - 1];
            }
        }
        return dp[n - 1]; 
    }
};

63. 不同路径 II

心得

  • 做好初始化,确定递归时候的条件即可,可以优化冗余代码,如判断条件可以上移到循环条件中
  • 虽然AC,但是遍历的时候判断条件过于冗余,其实初始化的时候即对阻碍点进行了数值上的限制,而自己通过判断上、左是否障碍来改变递推公式,其实初始化的0即保证了障碍的处理,但是这种情况需要对本点是够是障碍点做出判断,如果没有的话,左上不同条件涵盖了判断

题解

  • 空间可以从O(M*N)优化到O(M),但是不好理解,重点掌握第一种
class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        if (obstacleGrid[m - 1][n - 1] == 1 || obstacleGrid[0][0] == 1) return 0;
        vector<vector<int>> dp(m, vector<int>(n, 0));
        for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1;
        for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1;             
        for (int i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
                if (obstacleGrid[i][j] == 1) continue;
                dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

            }
        }
        return dp[m - 1][n - 1];
    }
};