一、62. 不同路径
题目链接:力扣
文章讲解:代码随想录
视频讲解: 栈的基本操作! | LeetCode:232.用栈实现队列动态规划中如何初始化很重要!| LeetCode:62.不同路径栈的基本操作! | LeetCode:232.用栈实现队列
题目:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
代码:
class Solution {
public:
int uniquePaths(int m, int n) {
/*vector<vector<int>> dp(m, vector<int> (n, 0));
for (int i = 0; i < n; i++) dp[0][i] = 1;
for (int j = 0; j < m; j++) dp[j][0] = 1;
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
{
dp[i][j] += dp[i][j-1] + dp[i-1][j];
}
}
return dp[m-1][n-1]*/
/*vector<int> dp(n, 1);
for (int i = 1; i < m; i++)
{
for (int j = 1; j < n; j++)
{
dp[j] += dp[j-1];
}
}
return dp[n-1];*/
//数论
long long numerator = 1; // 分子
int denominator = m - 1; // 分母
int count = m - 1;
int t = m + n - 2;
while(count--)
{
numerator *= t--;
while(denominator > 0 && numerator % denominator == 0)
{
numerator /= denominator--;
}
}
return numerator;
}
};
总结:1.动规:只从左和上方向增加数字,所以可以横着滚动遍历。2.数论:注意及时消去分母。否则容易溢出。
二、63. 不同路径 II
题目链接:力扣
文章讲解:代码随想录
视频讲解:动态规划,这次遇到障碍了| LeetCode:63. 不同路径 II
题目:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish”)。 现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径? 网格中的障碍物和空位置分别用 1 和 0 来表示。
代码:
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
if (obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1)
return 0;
/*vector<int> dp(obstacleGrid[0].size());
for (int i = 0; i < obstacleGrid[0].size(); i++)
{
if (obstacleGrid[0][i] == 1) dp[i] = 0;
else if (i == 0) dp[i] = 1;
else dp[i] = dp[i-1];
}
for (int i = 1; i < obstacleGrid.size(); i++)
{
for (int j = 0; j < obstacleGrid[0].size(); j++)
{
if (obstacleGrid[i][j] == 1) dp[j] = 0;
else if(j != 0) dp[j] += dp[j-1];
}
}
return dp.back();*/
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];
}
};
总结:对比上一题,只需判断有障碍物时清零即可。注意:初始化时,前一个有障碍物,后续都是0.