vlambda博客
学习文章列表

动态规划<6>不同路径II(unique-paths-ii)

本节为动态规划第六题:不同路径II(unique-paths-ii),主要包括:问题描述,算法思路,复杂度分析,C++实现。

1. 问题描述

  一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。现考虑网格中有障碍物,问总共有多少条不同的路径?


  网格中障碍物和空位置用1,0表示,m和n的值均不超过100。



示例:
  输入:
  [
   [0,0,0],
   [0,1,0],
   [0,0,0]
  ]
  输出: 2
  解释:
  3x3 网格的正中间有一个障碍物。
  从左上角到右下角一共有 2 条不同的路径:
  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

2. 动态规划解法

  根据没有障碍物的版本的问题,我们知道状态转移方程为:dp[i][j]=dp[i-1][j]+dp[i][j-1]。
  有障碍物的版本中需要额外的一些工作,算法思路如下:

  • 若第一个点dp[0][0]为1,则说明有障碍物,那么机器人不能做任何移动,返回0;

  • 如果dp[0][0]为0,没有障碍物,初始化这个值为1;

  • 遍历第一行,如果一个点初始值为1,说明有障碍物,没有路径可以通过,设值为0;否则dp[i,j]=dp[i,j-1]

  • 同样遍历第一列,初始值不为1则dp[i][j]=dp[i-1][j]

  • 从dp[1[[1]开始遍历数组,如果某个点初始无障碍,则dp[i][j]=dp[i-1][j]+dp[i][j-1];否则这个点设为0,保证不会对后面的路径有贡献。

  因为我们可以利用输入矩阵作为dp数组,所以空间复杂度O(1),时间复杂度O(m*n)。

//1.动态规划,时间复杂度O(m*n),空间复杂度O(1) int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int row_num = obstacleGrid.size(); int col_num = obstacleGrid[0].size(); if (obstacleGrid[0][0] == 1) return 0; obstacleGrid[0][0] = 1; for (int i = 1; i < row_num; i++) obstacleGrid[i][0] = (obstacleGrid[i][0] == 0 && obstacleGrid[i - 1][0] == 1) ? 1 : 0; for (int j = 1; j < col_num; j++) obstacleGrid[0][j] = (obstacleGrid[0][j] == 0 && obstacleGrid[0][j - 1] == 1) ? 1 : 0; for (int i = 1; i < row_num; i++) { for (int j = 1; j < col_num; j++) { if (obstacleGrid[i][j] == 0) obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]; else obstacleGrid[i][j] = 0; } } return obstacleGrid[row_num - 1][col_num - 1]; }


深度学习与数学

关注公号,发现更多

长按识别上方二维码关注