1. 程式人生 > >leetcode63-Unique Paths II/獨特路徑II

leetcode63-Unique Paths II/獨特路徑II

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.

一個機器人從一個mxn的網格左上角出發,只能向下或向右移動,最終要到達右下角,問可能有多少條不同的路徑。網格中有一些障礙物由1表示,見例一:

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.
有兩種途徑到達右下角:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

動態規劃:
使用dp陣列來儲存每一點可能的路徑數。我最開始想的是用三維陣列存,形成思維定勢了,但是太慢了。後來發現只能往右邊和下邊走,意味著不能返回,因此二維陣列就夠了。

class Solution {
    public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int rows = obstacleGrid.length;
        int cols = obstacleGrid[0].length;
        int[][] dp = new int[rows][cols]
; if (obstacleGrid[0][0] == 0) dp[0][0] = 1; for (int i = 1; i < rows; i++) { dp[i][0] = obstacleGrid[i][0] == 0 ? dp[i - 1][0] : 0; } for (int i = 1; i < cols; i++) { dp[0][i] = obstacleGrid[0][i] == 0 ? dp[0][i - 1] : 0; } for (int i = 1; i < rows; i++) { for (int j = 1; j < cols; j++) { dp[i][j] = obstacleGrid[i][j] == 1 ? 0 : dp[i - 1][j] + dp[i][j - 1]; } } return dp[rows - 1][cols - 1]; } }

後來又看了一下推薦解法,空間複雜度可以達到O(1),是用的原陣列存的dp陣列的內容。

程式碼:

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {

        int R = obstacleGrid.length;
        int C = obstacleGrid[0].length;

        // If the starting cell has an obstacle, then simply return as there would be
        // no paths to the destination.
        if (obstacleGrid[0][0] == 1) {
            return 0;
        }

        // Number of ways of reaching the starting cell = 1.
        obstacleGrid[0][0] = 1;

        // Filling the values for the first column
        for (int i = 1; i < R; i++) {
            obstacleGrid[i][0] = (obstacleGrid[i][0] == 0 && obstacleGrid[i - 1][0] == 1) ? 1 : 0;
        }

        // Filling the values for the first row
        for (int i = 1; i < C; i++) {
            obstacleGrid[0][i] = (obstacleGrid[0][i] == 0 && obstacleGrid[0][i - 1] == 1) ? 1 : 0;
        }

        // Starting from cell(1,1) fill up the values
        // No. of ways of reaching cell[i][j] = cell[i - 1][j] + cell[i][j - 1]
        // i.e. From above and left.
        for (int i = 1; i < R; i++) {
            for (int j = 1; j < C; j++) {
                if (obstacleGrid[i][j] == 0) {
                    obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1];
                } else {
                    obstacleGrid[i][j] = 0;
                }
            }
        }

        // Return value stored in rightmost bottommost cell. That is the destination.
        return obstacleGrid[R - 1][C - 1];
    }
}