Unique Paths II

https://oj.leetcode.com/problems/unique-paths-ii/

Follow up for "Unique Paths":

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.

For example,

There is one obstacle in the middle of a 3x3 grid as illustrated below.

[

  [0,0,0],

  [0,1,0],

  [0,0,0]

]

The total number of unique paths is 2.

Note: m and n will be at most 100.

解题思路:

这是一道带条件的dp。有了上一道题的基础,这题就比较简单了。注意几个不同点。

1. 判断的时候,不仅仅需要看obstacleGrid[i - 1][j]和obstacleGrid[i][j - 1],obstacleGrid[i][j]自己也需要考虑。一个为1的点,到不了自己。

2. 初始化的时候,不能将前一个点为0的点,就设置为1。应该是设置为前一个dp值。因为前面有1,直接就被挡掉了,无法到后面。其实也就是用下面的dp方法,不能粗想想都置为1了。

dp[i][j] = dp[i - 1][j] + dp[i][j - 1], if obstalcleGrid[i][j] == 0

           = 0, if obstacleGrid[i][j] == 1

public class Solution {

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

        int m = obstacleGrid.length;

        int n = obstacleGrid[0].length;

        int[][] dp = new int[m][n]; //dp[m][n]表示到点a[m][n]的不同路径数量,默认值为0

        

        if(obstacleGrid[0][0] == 0){

            dp[0][0] = 1;

        }

        for(int i = 1; i < n; i++){

            if(obstacleGrid[0][i - 1] == 0 && obstacleGrid[0][i] == 0){

                dp[0][i] = dp[0][i - 1];

            }

        }

        for(int i = 1; i < m; i++){

            if(obstacleGrid[i - 1][0] == 0 && obstacleGrid[i][0] == 0){

                dp[i][0] = dp[i - 1][0];

            }

        }

        for(int i = 1; i < m; i++){

            for(int j = 1; j < n; j++){

                if(obstacleGrid[i - 1][j] == 1 && obstacleGrid[i][j - 1] == 0 && obstacleGrid[i][j] == 0){

                    dp[i][j] = dp[i][j - 1];

                }

                if(obstacleGrid[i - 1][j] == 0 && obstacleGrid[i][j - 1] == 1 && obstacleGrid[i][j] == 0){

                    dp[i][j] = dp[i - 1][j];

                }

                if(obstacleGrid[i - 1][j] == 0 && obstacleGrid[i][j - 1] == 0 && obstacleGrid[i][j] == 0){

                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

                }

            }

        }

        return dp[m - 1][n - 1];

    }

}

 上面的还是有些复杂,改为下面的

public class Solution {

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

        int m = obstacleGrid.length;

        int n = obstacleGrid[0].length;

        int[][] dp = new int[m][n]; //dp[m][n]表示到点a[m][n]的不同路径数量,默认值为0

        

        if(obstacleGrid[0][0] == 0){

            dp[0][0] = 1;

        }

        for(int i = 1; i < n; i++){

            if(obstacleGrid[0][i] == 0){

                dp[0][i] = dp[0][i - 1];

            }

        }

        for(int i = 1; i < m; i++){

            if(obstacleGrid[i][0] == 0){

                dp[i][0] = dp[i - 1][0];

            }

        }

        for(int i = 1; i < m; i++){

            for(int j = 1; j < n; j++){

                if(obstacleGrid[i][j] == 0){

                    dp[i][j] = dp[i - 1][j] + dp[i][j - 1];

                }else{

                    dp[i][j] = 0;

                }

            }

        }

        return dp[m - 1][n - 1];

    }

}

与上题类似,这里也可以用一维数组解决问题。需要注意后面的循环必须判断j == 0,即若为第一列,那么如果该格!=1,直接继承上一列的dp就可以了。

public class Solution {

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

        int m = obstacleGrid.length;

        int n = obstacleGrid[0].length;

        int[] dp = new int[n]; //dp[m][n]表示到点a[m][n]的不同路径数量,默认值为0

        

        if(obstacleGrid[0][0] == 0){

            dp[0] = 1;

        }

        for(int i = 1; i < n; i++){

            if(obstacleGrid[0][i] == 0){

                dp[i] = dp[i - 1];

            }

        }

        

        for(int i = 1; i < m; i++){

            for(int j = 0; j < n; j++){

                if(obstacleGrid[i][j] == 0){

                    if(j > 0){

                        dp[j] = dp[j] + dp[j - 1];

                    }else{

                        dp[j] = dp[j];

                    }

                }else{

                    dp[j] = 0;

                }

            }

        }

        return dp[n - 1];

    }

}

针对第一行的初始化可以省去,仅仅初始化第一格即可。但是后面的外循环要从0开始。

public class Solution {

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

        int m = obstacleGrid.length;

        int n = obstacleGrid[0].length;

        int[] dp = new int[n]; //dp[m][n]表示到点a[m][n]的不同路径数量,默认值为0

        

        if(obstacleGrid[0][0] == 0){

            dp[0] = 1;

        }

        //初始化可省略

        //for(int i = 1; i < n; i++){

        //    if(obstacleGrid[0][i] == 0){

        //        dp[i] = dp[i - 1];

        //    }

        //}

        

        for(int i = 0; i < m; i++){

            for(int j = 0; j < n; j++){

                if(obstacleGrid[i][j] == 0){

                    if(j > 0){

                        dp[j] = dp[j] + dp[j - 1];

                    }else{

                        dp[j] = dp[j];

                    }

                }else{

                    dp[j] = 0;

                }

            }

        }

        return dp[n - 1];

    }

}

 

你可能感兴趣的:(unique)