zoukankan      html  css  js  c++  java
  • 63. Unique Paths II

    最后更新

    四刷?

    依然是尝试用一维DP。

    每次更新DP的时候相当于直接添加了2个方向的贡献值。

    开始的dp[1] = 1不好理解,其实是代表每行第一个格子dp[j]来自左边的贡献值,来自上面的贡献值是他本身,我们在上一行算过,所以是dp[j] + 1。

    下个格子dp[j+1]就变成了来自左边的贡献值 —— dp[j](刚刚算的) + 来自上面的贡献值 dp[j+1], 所以是dp[j+1] + dp[j]。。

    如果是障碍物直接是0,没啥可说的。

    Time: O(mn)
    Space: O(min(m,n))

    public class Solution {
        public int uniquePathsWithObstacles(int[][] obstacleGrid) {
            if (obstacleGrid.length == 0) return 0;
    
            
            int row = obstacleGrid.length;
            int col = obstacleGrid[0].length;
            
            int[] dp = new int[col + 1];
            dp[1] = 1;
            
            for (int i = 0; i < row; i++) {
                for (int j = 0; j < col; j++) {
                    if (obstacleGrid[i][j] == 1) {
                        dp[j+1] = 0;
                    } else {
                        dp[j+1] += dp[j];
                    }
                }
            }
            
            return dp[col];
        }
    }
    


    一刷

    小机器人走路的变体,典型DP。

    现在加了个条件,有障碍,那无非是有障碍的那格是0.

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

    Extra Space是n²,实际上不用,只需要2列,或者2行就行了。

    dp[i][j]是从当前列+前一列 得出来的,所以只记录这俩就够了。

    但是具体怎么实现没写代码,三刷再说吧。。


    三刷。

    二维DP记录就不说了。说说如何把m * n空间变成 M..

    到dp[m][n]的解来自于dp[m-1][n]和dp[m][n-1]

    遍历的时候是一行一行(一列一列)遍历的。

    dp[1][1]来自于dp[1][0]
    dp[2][1]来自于dp[2][0]
    dp[3][1]来自于dp[3][0]
    ..这是每个点更新时来自于横向或者纵向其中一个方向的贡献,然后还有另一个方向。
    问题是终归他们是相加的,不如先横向都加了,再总向把所有的和加起来。

    另一个地方是初始化,如果是0的话,需要判断一下最外层;这里手动添加了半圈,结果不影响。

    Time: O(nm)
    Space: O(n)

    public class Solution {
        public int uniquePathsWithObstacles(int[][] grid) {
            if (grid.length == 0) return 0;
            
            int[] dp = new int[grid[0].length + 1];
            dp[1] = 1;
            for (int i = 1; i <= grid.length; i++) {
                for (int j = 1; j <= grid[0].length; j++) {
                    if (grid[i-1][j-1] == 0) {
                        dp[j] += dp[j - 1];
                    } else {
                        dp[j] = 0;
                    }
                }
            }
            
            return dp[grid[0].length];
        }
    }
    
  • 相关阅读:
    mysql 忘记密码
    IE Webcontrols Treeview的一个bug及修正
    [原创]关于打开新窗口和关闭老窗口的2个方法!
    如何传值在2个页面之间 :要求不刷新父页面,并且不能用Querystring传值
    怎样才能用一个adsl帐号使两台机子同时上网?
    如何查找 文件的MIME类型
    [原创]利用DropDownlist来控制Textbox输入数字的精度
    动态添加Html单元格时,事件怎么写?如mouseover事件
    [原创]通过点击节点或选择节点前checkbox实现树节点单选功能!
    [原创]如何控制TreeView在打开的时候只展开两层?
  • 原文地址:https://www.cnblogs.com/reboot329/p/6128000.html
Copyright © 2011-2022 走看看