62. Unique Paths
空间可以按行优化为 O(n),也可以按列优化为O(m)。
class Solution { public: int uniquePaths(int m, int n) { int dp[m][n]={0}; dp[0][0]=1; for (int i=0;i<m;++i){ for (int j=0;j<n;++j){ if (i==0&&j==0) continue; dp[i][j]=0; if (j-1>=0) dp[i][j] += dp[i][j-1]; if (i-1>=0) dp[i][j] += dp[i-1][j]; } } return dp[m-1][n-1]; } };
63. Unique Paths II
和上一题一样,注意障碍物的地方为0就好。
class Solution { public: int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m=obstacleGrid.size(), n=obstacleGrid[0].size(); vector<vector<int>> dp(m,vector<int>(n,0)); dp[0][0] = obstacleGrid[0][0]==0?1:0; for (int i=0;i<m;++i){ for (int j=0;j<n;++j){ if (i==0 && j==0) continue; else if (obstacleGrid[i][j]==1) dp[i][j]=0; else if (j==0) dp[i][j]=dp[i-1][j]; else if (i==0) dp[i][j]=dp[i][j-1]; else dp[i][j] = dp[i-1][j]+dp[i][j-1]; } } return dp[m-1][n-1]; } };
Unique Path 变种 - Google 高频
从左上角走到右上角,要求每一步只能向正右、右上或右下走,即 →
按照列dp, dp[i][j] = dp[i-1][j-1] + dp[i][j-1] + dp[i+1][j-1], 注意i-1,i+1需要存在
followup1: 优化空间复杂度至 O(n)
可以 dp[m][2] 滚动数组做。如果就用一维 dp[m] 的话,需要一个变量prev去记录左上的值。
followup2: 给定矩形里的三个点,判断是否存在遍历这三个点的路经
画图观察就能发现规律。因为从每一格只能走三个方向,考虑两个格子 (x, y) 和 (i, j),当 (x, y) 能走到 (i, j) 的时候,(x, y) 会位于 (i, j) 向后张的扇形面积里面
用式子表达就是,i - dy <= x <= i + dy, where dy = j - y
排序(这边可以先想想怎么排序)之后只要发现一组不满足就不存在
followup3: 给定矩形里的三个点,找到遍历这三个点的所有路径数量
还是按照follow up 1的思路用滚动数组dp,但是如果当前列有需要到达的点时,只对该点进行dp,其他格子全部置零,表示我们只care这一列上经过目标点的路径
(如果一列上有多个需要达到的点,直接返回0)
followup4: 给定一个下界 (i == H),找到能经过给定下界的所有路径数量 (i >= H)
1:先dp一遍,得到所有到右上的路径数量
2:然后在 0<=i<=H, 0<=j<=cols 这个小矩形中再DP一遍得到不经过下界的所有路径数量
3:两个结果相减得到最终路径数量
可以重用follow up 1的代码
public int uniquePaths(int rows, int cols, int H) { return uniquePaths(rows, cols) - uniquePaths(H, cols); }
followup5: 起点和终点改成从左上到左下,每一步只能 ↓,求所有可能的路径数量
按行dp即可
Reference
https://www.1point3acres.com/bbs/thread-423857-1-1.html
原文地址:https://www.cnblogs.com/hankunyan/p/11479116.html