题目:62.不同路径、63. 不同路径 II
参考链接:代码随想录
62.不同路径
思路:dp五部曲。首先dp数组,dp[i][j]表示从[0,0]出发,到达[i,j]路径的数量,我们要求dp[m,n];递归公式,即从dp[i-1][j]往下移动一步,或者dp[i][j-1]往右移动一步,这两者相加,如果i本来就为0,那么dp[i-1][j]就不存在,因为本来就在第一行只可能右移无法下移;初始化,dp[0][0]=1,还可以把第一行和第一列的全部初始化为1;递归顺序,从左到右从上往下;举例略。时间复杂度O(mn)。本题初始化和遍历实际上混在一起了。
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];//定义二维数组
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(i==0||j==0){//在第一行或第一列
dp[i][j]=1;
}
else{
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
};
标答将初始化和转移分开了:
class Solution {
public:
int uniquePaths(int m, int n) {
vector<vector<int>> dp(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
for (int i = 1; i < m; i++) {
for (int j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
}
};
一维优化方法不好理解。
63. 不同路径 II
思路:本题多了障碍,还是同样五部曲。dp数组依旧表示到[i,j]的路径数;在求递归公式的时候,如果没有障碍,递归公式正常进行,一旦遇到障碍点,说明这个地方无法到达,故将其置为0;初始化的时候要注意,第一行和第一列一旦遇到障碍,后面都要置0;遍历顺序和举例略。时间复杂度O(mn)。
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m=obstacleGrid.size();
int n=obstacleGrid[0].size();
vector<vector<int>> dp(m,vector<int>(n,0));//初始化全为0,我们尽可能使用vector
for(int i=0;i<m;i++){
if(obstacleGrid[i][0]==0){
dp[i][0]=1;
}
else{
break;
}
}
for(int j=0;j<n;j++){
if(obstacleGrid[0][j]==0){
dp[0][j]=1;
}
else{
break;
}
}
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
if(obstacleGrid[i][j]==0){//没有障碍的时候
dp[i][j]=dp[i-1][j]+dp[i][j-1];
}
}
}
return dp[m-1][n-1];
}
};
看标答发现可以在初始化的时候稍微优化下代码:
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) //如果在起点或终点出现了障碍,直接返回0
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];
}
};
一维空间优化版本:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
if (obstacleGrid[0][0] == 1)
return 0;
vector<int> dp(obstacleGrid[0].size());
for (int j = 0; j < dp.size(); ++j)
if (obstacleGrid[0][j] == 1)
dp[j] = 0;
else if (j == 0)
dp[j] = 1;
else
dp[j] = dp[j-1];
for (int i = 1; i < obstacleGrid.size(); ++i)
for (int j = 0; j < dp.size(); ++j){
if (obstacleGrid[i][j] == 1)
dp[j] = 0;
else if (j != 0)
dp[j] = dp[j] + dp[j-1];
}
return dp.back();
}
};