《算法题讲解指南:动态规划算法--路径问题》--5.不同路径,6.不同路径II

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

5.不同路径

题目链接:

题目描述:

题目示例:

解法(动态规划):

算法思路:

C++算法代码:

算法总结及流程解析:

6.不同路径II

题目链接:

题目描述:

题目示例:

解法(动态规划):

算法思路:

C++算法代码:

算法总结及流程解析:

结束语


5.不同路径

题目链接:

62. 不同路径 - 力扣(LeetCode)

题目描述:

题目示例:

解法(动态规划):

算法思路:

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.「下标的映射关系」。

在本题中,「添加一行」,并且「添加一列」后,只需将dp01的位置初始化为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

题目链接:

63. 不同路径 II - 力扣(LeetCode)

题目描述:

题目示例:

解法(动态规划):

算法思路:

这道题算法逻辑和上面一题基本是十分类似的,唯一不同的在于状态转移方程,需要考虑有无障碍的情况:

状态转移方程:

简单分析一下。如果dpij表示到达i,j位置的方法数,那么到达i,j位置之前的一小步,有两种情况:

i.从i,j位置的上方(i -1,j的位置)向下走一步,转移到i,j位置;

ii.从i,j位置的左方(i,j- 1的位置)向右走一步,转移到i,j位置。

但是,i- 1,ji,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 这两道算法题就讲解完了。**不同路径,通过状态表示dpij记录到达(i,j)的路径数,状态转移方程为dpij=dpi-1j+dpij-1,并采用辅助结点技巧初始化。不同路径II,在第一题基础上增加了障碍物判断,遇到障碍物时路径数置0。**希望大家能有所收获!

相关推荐
凡人叶枫2 小时前
Effective C++ 条款30:透彻了解 inlining 的里里外外
linux·开发语言·c++·嵌入式开发·effective c++
noipp2 小时前
推荐题目:洛谷 P10907 [蓝桥杯 2024 国 B] 蚂蚁开会
c语言·c++·算法·编程·洛谷
学逆向的2 小时前
C++纯虚函数
开发语言·c++·网络安全
程序员二叉3 小时前
【JUC】线程池全套深度详解|参数|流程|拒绝策略|调优|异常处理
java·开发语言·jvm·算法·面试·juc
青山木3 小时前
Hot 100 --- 轮转数组
java·数据结构·算法
徐小夕3 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
凡人叶枫3 小时前
Effective C++ 条款22:将成员变量声明为 private
linux·开发语言·c++
北域码匠4 小时前
SHA-1算法:安全哈希原理与应用解析
算法·c#·哈希算法
坚果派·白晓明5 小时前
【鸿蒙PC】SDL3 移植:AtomCode Skills 4 步速通多媒体库适配
c++·华为·ai编程·harmonyos·atomcode·c/c++三方库
手写码匠5 小时前
手写 GraphRAG:从零实现图增强检索增强生成系统
人工智能·深度学习·算法·aigc