
🔥小叶-duck:个人主页
❄️个人专栏:《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法
✨未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游
目录
5.不同路径
题目链接:
题目描述:

题目示例:

解法(动态规划):
算法思路:
1.状态表示:
对于这种「路径类」的问题,我们的状态表示一般有两种形式:
i.从[i,j]位置出发,巴拉巴拉;
ii.从起始位置出发,到达[i,j]位置,巴拉巴拉。
这里选择第二种定义状态表示的方式:
dp[ i ][ j ]表示:走到[i,j]位置处,一共有多少种方式。
2.状态转移方程:
简单分析一下。如果dp[ i ][ j ]表示到达[i,j]位置的方法数,那么到达[i,j]位置之前的一小步,有两种情况:
i.从[[i,j]位置的上方([i - 1,j]的位置)向下走一步,转移到[i,j]位置;
ii.从[i,j]位置的左方([i,j-1]的位置)向右走一步,转移到[i,j]位置。
由于我们要求的是有多少种方法,因此状态转移方程就呼之欲出了:dp[ i ][ j ]=dp[ i - 1 ][ j ] + dp[ i ][ j - 1 ]。
3.初始化:
可以在最前面加上一个「辅助结点」,帮助我们初始化。使用这种技巧要注意两个点:
i,辅助结点里面的值要「保证后续填表是正确的」;
ii.「下标的映射关系」。
在本题中,「添加一行」,并且「添加一列」后,只需将dp[0][1]的位置初始化为1即可。
4.填表顺序:
根据「状态转移方程」的推导来看,填表的顺序就是「从上往下」填每一行,在填写每一行的时候「从左往右」。
5.返回值:
根据「状态表示」,我们要返回dp[ m ][ n ]的值。
C++算法代码:
cpp
class Solution {
public:
int uniquePaths(int m, int n)
{
//1、创建 dp 表
//2、初始化
//3、填表
//4、返回值
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
dp[0][1] = 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][n];
}
};
算法总结及流程解析:


6.不同路径II
题目链接:
题目描述:

题目示例:

解法(动态规划):
算法思路:
这道题算法逻辑和上面一题基本是十分类似的,唯一不同的在于状态转移方程,需要考虑有无障碍的情况:
状态转移方程:
简单分析一下。如果dp[i][j]表示到达[i,j]位置的方法数,那么到达[i,j]位置之前的一小步,有两种情况:
i.从[i,j]位置的上方([i -1,j]的位置)向下走一步,转移到[i,j]位置;
ii.从[i,j]位置的左方([i,j- 1]的位置)向右走一步,转移到[i,j]位置。
但是,[i- 1,j]与[i,j- 1]位置都是可能有障碍的,此时从上面或者左边是不可能到达[i,j]位置的,也就是说,此时的方法数应该是0。
由此我们可以得出一个结论,只要这个位置上「有障碍物」,那么我们就不需要计算这个位置上的值,直接让它等于0即可。
C++算法代码:
cpp
class Solution {
public:
int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid)
{
//1、创建 dp 表
//2、初始化
//3、填表
//4、返回值
int m = obstacleGrid.size();
int n = obstacleGrid[0].size();
vector<vector<int>> dp(m + 1, vector<int>(n + 1));
dp[0][1] = 1;
for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= n; j++)
{
if(obstacleGrid[i - 1][j - 1] == 0)//一定要注意dp数组和题目数组的映射关系
{
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
}
return dp[m][n];
}
};
算法总结及流程解析:


结束语
到此,5.不同路径,6.不同路径II 这两道算法题就讲解完了。**不同路径,通过状态表示dp[i][j]记录到达(i,j)的路径数,状态转移方程为dp[i][j]=dp[i-1][j]+dp[i][j-1],并采用辅助结点技巧初始化。不同路径II,在第一题基础上增加了障碍物判断,遇到障碍物时路径数置0。**希望大家能有所收获!