1. 程式人生 > >【LeetCode】63. Unique Paths II

【LeetCode】63. Unique Paths II

63. Unique Paths II

Description:

A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below).

Now consider if some obstacles are added to the grids. How many unique paths would there be?

An obstacle and empty space is marked as 1 and 0 respectively in the grid.

Note: m and n will be at most 100.

Example 1:

Input:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
Output: 2
Explanation:
There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

解題思路:

(1)動態規劃

動態規劃三要素:

1. 最優子結構:我們發現除去第一行第一列,其他dp二維陣列中的資料都是由它上面格子和左邊格子資料之和。如果有障礙物,那麼dp表格對應的位置為0。

2. 邊界條件:

  • 如果obstacleGrid表格中第一行、第一列都沒有障礙物,那麼dp表格中第一行、第一列都為1。
  • 如果start位置(即obstacleGrid[0][0]==1)有障礙物,那麼不管obstacleGrid表格後邊是什麼,路徑和都為0。
  • 如果obstacleGrid表格中第一行第i列有障礙物,那麼dp表格中第一行第i列後邊都為0。
  • 如果obstacleGrid表格中第一列第i行有障礙物,那麼dp表格中第一列第i行後邊都為0。

3. 狀態轉移方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]

已經AC的程式碼:

class Solution:
    def uniquePathsWithObstacles(self, obstacleGrid):
        """
        :type obstacleGrid: List[List[int]]
        :rtype: int
        """
        if not obstacleGrid:
            return 0
        row = len(obstacleGrid)
        col = len(obstacleGrid[0])
        if obstacleGrid[0][0] == 1:
            return 0
        dp = [[1 for i in range(col)] for i in range(row)]
        for i in range(col):
            if obstacleGrid[0][i] == 1:
                for j in range(i,col):
                    dp[0][j] = 0
                break
        for i in range(row):
            if obstacleGrid[i][0] == 1:
                for j in range(i,row):
                    dp[j][0] = 0
                break
        for i in range(1,row):
            for j in range(1,col):
                if(obstacleGrid[i][j]) == 1:
                    dp[i][j] = 0
                else:
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]

solution = Solution()
obstacleGrid = [[0,0],[1,1],[0,0]]
print(solution.uniquePathsWithObstacles(obstacleGrid))

上面程式碼邏輯清晰,但是不夠簡潔。重新整理上邊分析的解題思路,可以寫出如下簡化程式碼:

class Solution:

    def uniquePathsWithObstacles(self, obstacleGrid):
        """
        :type obstacleGrid: List[List[int]]
        :rtype: int
        """
        row = len(obstacleGrid)
        col = len(obstacleGrid[0])
        dp = [[1] * col for _ in range(row)]

        for i in range(0, row):
            for j in range(0, col):
                if obstacleGrid[i][j]:
                    dp[i][j] = 0
                elif i == 0:
                    dp[i][j] = dp[i][j-1]
                elif j == 0:
                    dp[i][j] = dp[i-1][j]
                else:
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]
        return dp[-1][-1]

solution = Solution()
obstacleGrid = [[0,0],[1,1],[0,0]]
print(solution.uniquePathsWithObstacles(obstacleGrid))