在问 · 算法题解

63. 不同路径 II

题目描述

输入一个 m x n 的网格 obstacleGrid,格子里的 1 表示障碍,0 表示可以通行。

机器人从左上角 obstacleGrid[0][0] 出发,要走到右下角 obstacleGrid[m - 1][n - 1]。每一步只能向右或向下走一格,途经的格子(含起点和终点)都不能是障碍。

返回不同路线的数量。若起点或终点本身是障碍,答案为 0。

示例 1
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2

解释:正中间有障碍,只剩两条路:右右下下、下下右右。

示例 2
输入:obstacleGrid = [[0,1],[0,0]]
输出:1

解释:右上角是障碍,只能先向下再向右。

数据范围

  • m == obstacleGrid.length
  • n == obstacleGrid[i].length
  • 1 <= m, n <= 100
  • obstacleGrid[i][j] 只会是 0 或 1。
  • 保证答案不超过 2 * 10^9。

解题思路

到达格子 (i,j) 的路径数 = 从上方来的路径数 + 从左边来的路径数;障碍格的路径数为 0。只用一行数组 dp:更新前 dp[j] 是上一行同列的值(上方),dp[j-1] 已是本行左边格的值,所以 dp[j] += dp[j-1]。

为什么正确

处理完 (i,j) 后,dp[0..j] 是第 i 行的答案,dp[j+1..] 仍是第 i-1 行的答案。

复杂度分析

时间 O(mn),空间 O(n)。

易错点

第 0 列的格子只能从上方来,不能加 dp[j-1];但遇到障碍仍要置 0,之后整列都会是 0。起点本身是障碍时答案为 0。

参考代码

Python、Java、C++、Go、JavaScript、TypeScript 六种语言,逻辑一致。

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:
        m, n = len(obstacleGrid), len(obstacleGrid[0])
        dp = [0] * n
        dp[0] = 1
        for i in range(m):
            for j in range(n):
                if obstacleGrid[i][j] == 1:
                    dp[j] = 0
                elif j > 0:
                    dp[j] += dp[j - 1]
        return dp[n - 1]

载入编辑器,自己跑一遍 →

动态规划 专题的其他题目

查看 动态规划 全部题目 →