题目描述

[LeetCode 63] 不同路径 II
示例 1:

输入:
[
[0,0,0],
[0,1,0],
[0,0,0]
]
输出: 2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右

题目分析

这道题的意思就是从左上角的点开始遍历,一直遍历到右下角,如果为1则跳过,如果为0则可以运行。由于这种题要判断状态和状态的转移方程,所以动态规划是最好的方式了。不然也可以用回溯了。

源码

class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
    if(obstacleGrid==null){
      return 0;  
    }
    int row=obstacleGrid.length;
    int col=obstacleGrid[0].length;
    if(row==0||col==0){
     return 0;   
    }
    //一行一列必定不通
    int[][] dp=new int[row][col];
    for(int i=0;i<row;i++){
        for(int j=0;j<col;j++){
            if(obstacleGrid[i][j]==0){
                if(i==0&&j==0){
                   dp[i][j]=1;
                }
                else if(i==0){
                    dp[i][j]=dp[i][j-1];
                }
                
                else if(j==0){
                    dp[i][j]=dp[i-1][j];
                }
                else{
                    dp[i][j]=dp[i-1][j]+dp[i][j-1];
                    //把路径全加起来
                }
            }
        }
    }
    return dp[row-1][col-1];
}
}

改进

思路就是动态规划啦,不过可以去遍历然后一个一个判断。要说用第二种方法的话,我会选择初始化加上递归的思想,虽然其实就是第一种方法的改写啦。

改进代码

        int m=obstacleGrid.length,n=obstacleGrid[0].length;
        int a[][] = new int[m][n];
        int i;
        i=0;
        //初始化行
        while (i < m) {
            if(obstacleGrid[i][0]==0){
                a[i][0]=1;
            }else{
                break;
            }
            i++;
        }
        while(i<m){
            a[i][0]=0;
            i++;
        }
        i=0;
        //初始化列
        while (i < n) {
            if(obstacleGrid[0][i]==0){
                a[0][i]=1;
            }else{
                break;
            }
            i++;
        }
        while(i<n){
            a[0][i]=0;
            i++;
        }
        //带判断条件的动态规划
        for (i = 1; i < m; i++) {
            for (int j = 1; j < n; j++) {
               if(obstacleGrid[i][j]==1){
                   a[i][j]=0;
               }else{
                   a[i][j]=a[i-1][j]+a[i][j-1];
               }
            }
        }
        return a[m-1][n-1];
}
}

分析

第一个时间复杂度为O(n^2)
第二个时间复杂度为O(n^2)但是空间复杂度会相对高一点了吧

难点

这道题难度就在于比不同路径I多了一个障碍物。对于不同路径I我可以直接用排列组合的方式来做,这一题就不行了,只能老老实实的动态规划,搞清楚每个状态和状态的转移方程。

小结

这道题的难点就在于搞清楚状态转移方程,遍历时自动避开障碍物,然后障碍物向下向右都是不可能的,所以用条件语句来限制,最后把步数全加起来就行了。

[1]https://leetcode-cn.com/problems/unique-paths-ii/comments/

相关文章:

  • 2021-09-03
  • 2022-01-07
  • 2021-06-10
  • 2022-12-23
  • 2021-06-01
  • 2022-01-03
猜你喜欢
  • 2021-09-27
  • 2021-08-04
  • 2021-12-07
  • 2022-02-18
  • 2022-12-23
  • 2021-11-09
  • 2021-08-23
相关资源
相似解决方案