1 題目描述
給定一個m x n的矩陣,找到一條從左上角到右下角的最小路徑和。每次只能向右或是向下移動,但是他中間有障礙物,所以要避開障礙物。
2 解法
這題與LeetCode 課前預習 - 掌握 Dynamic Programming 的思維指南的題目類似,如果你會做Leetcode-62-Unique Paths,這題也是一樣的概念,只是這題有障礙物,因此碰到障礙物就要記得把路徑設定為0。
2.1 Iterative
因為已經做過類似的題目,所以直接從Iterative下手,我的想法是這樣的:
- 今天邊緣也有可能有障礙物,所以要從邊緣開始處理
- 如果碰到障礙物,就把路徑設定為0
- 其他的就是從上面或是左邊來的路徑和
1 2 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就好
1 2 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的空間就好。