機器人從左上角走到右下角,只能向右/向下移動。網格中 0 表示通路,1 表示障礙物。求不同路徑數。
範例:
輸入: [[0,0,0],[0,1,0],[0,0,0]]
輸出: 2
路徑: 右→右→下→下、下→下→右→右
同「不同路徑 I」,但障礙格路徑數為 0:
dp[i][j] 表示到達 (i,j) 的路徑數obstacleGrid[i][j] == 1:dp[i][j] = 0dp[i][j] = dp[i-1][j] + dp[i][j-1]時間複雜度:O(mn),空間複雜度:O(mn)(可優化至 O(n))。
class Solution:
def uniquePathsWithObstacles(self, obstacleGrid):
"""
:type obstacleGrid: List[List[int]]
:rtype: int
"""
if not obstacleGrid or obstacleGrid[0][0] == 1:
return 0
m, n = len(obstacleGrid), len(obstacleGrid[0])
dp = [[0] * n for _ in range(m)]
dp[0][0] = 1
# 首列
for i in range(1, m):
dp[i][0] = dp[i-1][0] if obstacleGrid[i][0] == 0 else 0
# 首行
for j in range(1, n):
dp[0][j] = dp[0][j-1] if obstacleGrid[0][j] == 0 else 0
for i in range(1, m):
for j in range(1, n):
if obstacleGrid[i][j] == 1:
dp[i][j] = 0
else:
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
# 測試
if __name__ == "__main__":
sol = Solution()
assert sol.uniquePathsWithObstacles([[0,0,0],[0,1,0],[0,0,0]]) == 2
assert sol.uniquePathsWithObstacles([[1]]) == 0
assert sol.uniquePathsWithObstacles([[0,1],[0,0]]) == 1
print("所有測試通過")
def uniquePathsWithObstacles(self, obstacleGrid):
if not obstacleGrid or obstacleGrid[0][0] == 1:
return 0
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[-1]
dp[i][j] = 0 自然切斷通過該格的所有路徑dp[j] += dp[j-1] 原地更新,障礙處歸零obstacleGrid[0][0] == 1 直接返回 0不同路徑 II 是網格 DP 入門進階題,在基礎遞推上增加「狀態禁用」邏輯,掌握後可解決「帶陷阱/代價/限制」的網格路徑問題。