Unique Paths

原题链接Unique Paths

计算从左上角有多少条不同的路径可以到达右下角,移动方向只能是向右和向下。

对于每个位置,都有两种移动的可能,即向右移动和向下移动。可以用深度优先(dfs)解决,同时为了解决重复计算,可以用动态规划的思想,记录从dp[i][j]到达右下角有多少条不同的路径。

除了深度优先之外,可以用迭代法执行动态规划,这样做可以减少dp的维度,只需要一维数组即可,不过要改变dp的含义,假设当前所在位置为(m, n),那么dp[n]代表从左上角到达当前位置的不同路径书,原因为

  • 移动方向只能向右和向下,所以只要向下移动一行,就不能再返回上一行。这说明,对于行的记录是可以忽略的。
  • 只要遍历每一行的每一列,不断更新dp[n]直到到达右下角即可,假设当前在第m行的第n列,那么dp[n]表示从左上角开始移动可以有多少条不同的路径达到第m行第n列
  • 对于每个位置,它可以从上一行的当前列向下移动到达当前位置,也可以从当前行的上一列向右移动到达当前位置
  • 所以dp[n] = dp[n] + dp[n - 1],dp[n]代表从上一行的第n列到达右下角的不同路径数,dp[n - 1]代表从当前行的第n-1列到达右下角的不同路径数
  • 直到遍历到右下角,即遍历了所有行所有列,那么dp[n]就代表从左上角到达右下角的不同路径数

代码如下

class Solution {
public:int uniquePaths(int m, int n) {/* 到达第0行,第j列的路径数只有1条 */vector<int> dp(n, 1);/* 这里直接忽略了第0行和第0列,原因是到达第0行和第0列的某个位置的路径都只有1条 */for(int i = 1; i < m; ++i){for(int j = 1; j < n; ++j){/* dp[j]表示从左上角到达第i行第j列的不同路径数 *//* 当i为m-1,j为n-1时,就是从左上角到达右下角的不同路径数 */dp[j] = dp[j] + dp[j - 1];}}return dp[n - 1];}
};

Unique Paths II

原题链接Unique Paths II

接着上面的问题,如果某些位置有障碍物,那么有多少条路径可以到达右下角。
移动的过程中不能到达障碍物所在的位置。

方法和上面一样,仍然有一维数组记录到达某一列的不同路径,不过需要判断某个位置是否有障碍物,如果有,那么dp[n]为0,否则dp[n] = dp[n - 1] + dp[n]

另外,对于dp[0]要特殊处理,不能像上面一样直接从第一行第一列开始,因为第0行第0列都可能存在障碍物导致dp[n[不是1而是0.

代码如下

class Solution {
public:int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {if(obstacleGrid.empty())return 0;int m = obstacleGrid.size();int n = obstacleGrid[0].size();/* 如果起始位置和目标位置都有障碍物,那么就不可能到达 */if(n == 0 || obstacleGrid[0][0] == 1 || obstacleGrid[m-1][n-1] == 1)return 0;vector<int> dp(n);/* 到达开始位置的路径为1 */dp[0] = 1;/* 到达第0行的某个位置的路径,有障碍物的话后面就都是0,否则是1 */for(int i = 1; i < n; ++i)dp[i] = (obstacleGrid[0][i] == 1) ? 0 : dp[i - 1];for(int i = 1; i < m; ++i){/* 如果当前行的第0列是障碍物,那么到达当前行的第0列的路径数为0 */if(obstacleGrid[i][0] == 1)dp[0] = 0;for(int j = 1; j < n; ++j){dp[j] = obstacleGrid[i][j] == 1 ? 0 : dp[j] + dp[j - 1];}}return dp[n - 1];}
};

原题链接Minimum Path Sum

和上面的题一样,只是这回要求是找到路径长度最短的那一条,路径长度是路径上所有数字的和

仍然采用迭代法的动态规划,不过要改变dp的含义,即dp[n]表示从左上角到达当前位置的最小路径长,而不在是不同路径数

另外,第一行和第一列不再单纯的是1,而是数字累加,代表路径长
代码如下

class Solution {
public:int minPathSum(vector<vector<int>>& grid) {int m = grid.size();if(m == 0) { return 0; }int n = grid[0].size();if(n == 0) { return 0; }vector<int> dp(n, 0);dp[0] = grid[0][0];/* 这里第一行的路径长要累加 */for(int i = 1; i < n; ++i)dp[i] = dp[i - 1] + grid[0][i];for(int i = 1; i < m; ++i){/* 第一列也要累加 */dp[0] += grid[i][0];for(int j = 1; j < n; ++j){/* 不再是相加,而是找到较小的那个 */dp[j] = std::min(dp[j], dp[j - 1]) + grid[i][j];}}return dp[n - 1];}
};

上面三道题主要利用动态规划的思想,另外通过迭代法简化动态规划数组的维度。

每天一道LeetCode-----计算从二维数组的左上角到达右下角的所有路径数及最短的那条,如果存在障碍物时又是多少相关推荐

  1. 每天一道LeetCode-----在有序的二维数组中查找某个元素

    原题链接Search a 2D Matrix 判断一个二维数组中是否存在某个值 该数组满足 每一行元素按从左到右递增顺序排列 当前行的第一个元素大于上一行的最后一个元素 假设二维数组的维度是m × n ...

  2. 【C语言指针题】编写函数实现在任意行、任意列的二维数组中寻找鞍点,行、列数均有主调函数传入。

    [代码] #include <stdio.h> #include <stdlib.h> #define M 3 #define N 4 void seek(int (*p)[N ...

  3. java二维数组模拟用户登录_Java 语言基础编程题 (二维数组, 五子棋游戏, 实体类和接口)...

    这里分享三道编程题, 下面是我个人的视频讲解我的解题思路以及代码运行演示https://www.zhihu.com/video/1253424180936724480 1. 编程实现以下需求: 定义一 ...

  4. 实体类 接口_Java 语言基础编程题 (二维数组, 五子棋游戏, 实体类和接口)

    原文:Java 语言基础编程题 (二维数组, 五子棋游戏, 实体类和接口, 视频讲解) 这里分享三道编程题, 下面是我个人的视频讲解 二维数组, 五子棋游戏, 实体类和接口_哔哩哔哩 (゜-゜)つロ ...

  5. javascript读取文本文件到二维数组代码_十行代码说清楚:leetcode 二维数组中的查找...

    剑指 Offer 04. 二维数组中的查找 这道题是将一维的二分查找扩展为二维数组中的二分查找. 关键点有 3 处: 起始点的选择 大于 target 时坐标的变化 小于 target 时坐标的变化 ...

  6. 图像转换为二维数组存入DSP6748

     版权声明:本文为博主原创文章,未经博主允许不得转载.博客不用于商业活动,博主对博客的使用,拥有最终解释权  本文为原创作品,未经本人同意,禁止转载,禁止用于商业用途!本人对博客使用拥有最终解释权 ...

  7. 江哥带你玩转C语言| 12 -二维数组和字符串

    二维数组 所谓二维数组就是一个一维数组的每个元素又被声明为一 维数组,从而构成二维数组. 可以说二维数组是特殊的一维数组. 示例: int a[2][3] = { {80,75,92}, {61,65 ...

  8. c语言二维数组行和列怎么看,二维数组行列怎么看

    c语言中如何获取一个二维数组的行列数? 有两种方式: 1 二维数组的行列数在定义的时候就是确定好的,所以编程人员是知道二维数组的大小以及行列数的. 所以可以直接使用行列数的值. 为方便维护,可以将行列 ...

  9. 学习笔记_给二维数组赋值

    实例一 P89 给二维数组赋值 2020-03-20 12:27:11 一个私人书柜有3层2列,分别向该书柜第1层1列放入历史类读物,向该书柜第二层第一例放入经济类读物,向第二层第二列放入现代科学读物 ...

最新文章

  1. 机器学习中的数据泄露是什么?构建模型中如何防止数据泄露?正确的方案是什么?如何使用pipeline防止数据泄露?
  2. golang应用日志
  3. CentOS系统时间同步(NTP)
  4. 金士顿u盘分区工具_使用U盘工具给电脑硬盘快速分区教程
  5. datatable修改csv的最后一列
  6. WebService学习总结——调用第三方提供的webService服务
  7. UNIX(进程间通信):03---僵尸进程
  8. docker代理设置ssl证书_docker - 设置HTTP/HTTPS 代理
  9. echarts legend不显示_ECharts地图系列一(定制区域水波纹显示,以及其他区域圆点颜色不统一)...
  10. 美团回应无法使用微信支付:耽误大家干饭了,对不起
  11. 怎么用eclipse编写python_python用eclipse开发配置
  12. Win10下安装不同版本的MySQL
  13. 计算机系统-电路设计10-寄存器的内部电路实现(输入与输出不同线)
  14. mysql 从库升级为主库的步骤
  15. HTML显示波形,CSS3波形loading动画特效
  16. 简单直观理解形态学中的开运算和闭运算
  17. 《Windows via C/C++》学习笔记 —— 用户模式的“线程同步”之“条件变量”
  18. VBA 如何多条件查询汇总
  19. linux根分区inode满了该怎么办,linux inode已满解决方法 新的问题No space left on device...
  20. 产品生命周期管理PLM技术研究

热门文章

  1. 驱动备份工具哪个好_原神元素反应工具人推荐一览 元素反应工具人哪个好
  2. Java黑皮书课后题第9章:*9.5(使用GregorianCalendar类)Java API中有一个位于包java.util中的类GregorianCalendar
  3. C语言学习之利用指针输出二维数组任一行任一列元素的值
  4. C语言学习之输入一个大于三的值判断是否为素数
  5. 日志 php_高性能的PHP日志系统 SeasLog 使用
  6. pipeline 流水线设计
  7. Cocos2dx-如何利用NDK分析崩溃日志
  8. 一步一步学Silverlight 2系列(22):在Silverlight中如何用JavaScript调用.NET代码
  9. weblogic常见漏洞
  10. 中班音乐计算机反思,中班歌曲《不再麻烦好妈妈》活动反思