2021-09-22

不同路径2

题目描述

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
在这里插入图片描述

网格中的障碍物和空位置分别用 1 和 0 来表示。

遇到的坑

首先说说 创建二维数组是遇到的坑
一开始用

var flag = new Array(m).fill(new Array(n).fill(0))

但是当我想改变数组中的某一个值的时候,一整列的值都改变了。
原因是:数组是引用类型,数组变量存储在栈,元素数据存储在堆中,将数组赋值不同的对象,所以赋值对象都指向堆同一数据,所以改变其中一个数组中的元素,别的数组元素也会改变。
最后改用

var flag = new Array()
    for(var k=0; k<m; k++)
      flag[k] = new Array(n).fill(0)

创建二维数组。

解题思路

代码随想录他动态规划讲得特别好,可以去看看
我的思路和他的差不多 但是他描述的更好,我就借鉴一下,给自己加深一边思路
动态规划五部曲
(1)确定dp数组以及下标的含义
flag[i][j] :表示从(0 ,0)出发,到(i, j) 有flag[i][j]条不同的路径。
(2)确定递推公式
递推公式:flag[i][j] = flag[i][j-1] + flag[i-1][j]
但是需要注意,因为有了障碍,(i,j)如果是障碍就应该保持初始状态(初始状态为0)
此部分的代码为:

if(obstacleGrid[i][j] != 1)
      flag[i][j] = flag[i-1][j] + flag[i][j-1]

(3)flag数组如何初始化
因为从(0,0)到(i,0)的路径只有一套,所以flag[i][0]的路径只有一条,同理flag[0][j]
但如果(i,0)这条边遇到障碍之后,障碍之后的路就都走不通了,所以障碍之后的flag(i,0)应该都是0
此部分的代码为:

for (var i=0;i<m && obstacleGrid[i][0] == 0; i++) flag[i][0] = 1
for (var j=0;j<n && obstacleGrid[0][j] == 0; j++) flag[0][j] = 1

(4)确定遍历顺序
从递归公式flag[i][j] = flag[i - 1][j] + flag[i][j - 1] 中可以看出,一定是从左到右一层一层遍历,这样保证推导flag[i][j]的时候,flag[i - 1][j] 和 flag[i][j - 1]一定是有数值。

for(var i=1;i<m;i++){
      for (var j=1;j<n;j++){
        if(obstacleGrid[i][j] != 1)
          flag[i][j] = flag[i-1][j] + flag[i][j-1]
      }
    }

(5)打印数组 进行检查
本题整个的解题代码如下:

var uniquePathsWithObstacles = function(obstacleGrid) {
      var m = obstacleGrid.length
      var n = obstacleGrid[0].length
      // 创建一个用0填充的二维数组
      var flag = new Array()
      for(var k=0; k<m; k++)
        flag[k] = new Array(n).fill(0)
      if(m ==0 || n==0) return 0
      if(m==1 && n==1){
          if(obstacleGrid[0][0] == 1)
            return 0
          else 
            return 1
      }
      if(m>0 && n>0){
          if(obstacleGrid[0][0] == 1)
              return 0
          for (var i=0;i<m && obstacleGrid[i][0] == 0; i++) flag[i][0] = 1
          for (var j=0;j<n && obstacleGrid[0][j] == 0; j++) flag[0][j] = 1
          for(var i=1;i<m;i++){
            for (var j=1;j<n;j++){
              if(obstacleGrid[i][j] != 1)
                flag[i][j] = flag[i-1][j] + flag[i][j-1]
            }
          }
        return flag[m-1][n-1]
      }    
    };
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值