1 題目描述


給定一個m x n的矩陣,找到一條從左上角到右下角的最小路徑和。每次只能向右或是向下移動,但是他中間有障礙物,所以要避開障礙物。
2 解法
這題與LeetCode 課前預習 - 掌握 Dynamic Programming 的思維指南的題目類似,如果你會做Leetcode-62-Unique Paths,這題也是一樣的概念,只是這題有障礙物,因此碰到障礙物就要記得把路徑設定為0。
2.1 Iterative
因為已經做過類似的題目,所以直接從Iterative下手,我的想法是這樣的:
- 今天邊緣也有可能有障礙物,所以要從邊緣開始處理
- 如果碰到障礙物,就把路徑設定為0
- 其他的就是從上面或是左邊來的路徑和
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 
 | def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int:rows = len(obstacleGrid)
 columns = len(obstacleGrid[0])
 dp = [[0] * columns for _ in range(rows)]
 
 dp[rows-1][columns-1] = 1
 
 
 for row in range(rows - 1, -1, -1):
 for column in range(columns - 1, -1, -1):
 
 if obstacleGrid[row][column] == 1:
 dp[row][column] = 0
 
 elif dp[row][column] == 0:
 down, left = 0, 0
 
 if row < rows-1 and dp[row+1][column] is not None:
 down = dp[row+1][column]
 
 if column < columns-1 and dp[row][column+1] is not None:
 left = dp[row][column+1]
 dp[row][column] = down + left
 
 return dp[0][0]
 
 | 
這題也有一樣的思路,可以dp只用兩個row就好
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 
 | def uniquePathsWithObstacles2(self, obstacleGrid: List[List[int]]) -> int:rows = len(obstacleGrid)
 columns = len(obstacleGrid[0])
 
 dp = [[0] * columns for _ in range(2)]
 dp[0][columns-1] = 1
 
 for row in range(rows - 1, -1, -1):
 for column in range(columns - 1, -1, -1):
 if obstacleGrid[row][column] == 1:
 dp[0][column] = 0
 elif not(row == rows-1 and column == columns-1):
 down, left = 0, 0
 if row < rows - 1 and dp[1][column] is not None:
 down = dp[1][column]
 if column < columns - 1 and dp[0][column + 1] is not None:
 left = dp[0][column + 1]
 dp[0][column] = down + left
 
 dp[1] = copy.deepcopy(dp[0])
 
 return dp[0][0]
 
 | 
3 總結
這題不難,也是很快就寫出來了,只是在處理邊緣的時候要注意不要超過邊界,以及要處理障礙物的情況。這題的時間複雜度是O(n * m),空間複雜度是O(n * m)。如果你想要優化空間複雜度,可以參考上面的解法,只用兩個row的空間就好。