• 【Unique Paths II】cpp


    题目:

    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.

    代码:

    class Solution {
    public:
            int uniquePathsWithObstacles(vector<vector<int> >& obstacleGrid) 
            {
                const int m = obstacleGrid.size();
                const int n = obstacleGrid[0].size();
                vector<vector<int> > cache(m+1,vector<int>(n+1,0));
                return Solution::dfs(m, n, cache, obstacleGrid);
            }
            static int dfs( int i, int j, vector<vector<int> >& cache, vector<vector<int> >& obstacleGrid )
            {
                if ( i<1 || j<1 || obstacleGrid[i-1][j-1]==1 ) return 0;
                if ( i==1 && j==1 ) return 1;
                return Solution::getDFS(i-1, j, obstacleGrid, cache) + Solution::getDFS(i, j-1, obstacleGrid, cache);
            }
            static int getDFS(int i, int j, vector<vector<int> >& obstacleGrid, vector<vector<int> >& cache)
            {
                if ( cache[i][j]>0 ){
                    return cache[i][j];
                }
                else{
                    return cache[i][j] = Solution::dfs(i, j, cache, obstacleGrid);
                }
            }
    };

    tips:

    上述的代码采用了深搜+缓存(“备忘录”)法。照比Unique Paths多了一个判断条件,如果obstacleGrid上该位置为1则直接返回0。

    有个细节上的技巧:

    obstacleGrid是题目给出的定义,下标[m-1][n-1]

    cache是自定义的缓存数组,下标[m][n]

    同样的位置,cache的坐标比obstacleGrid大1;因此,只要深搜过程中保证了cache的坐标在合理范围内,无论是横坐标-1还是纵坐标-1,映射到cache的坐标中总不会越界。

    上述代码的效率并不高,但是比较容易处理各种case。再尝试动态规划的解法。

    ==========================================

    在Unique Paths的基础上,用动规又把Unqiue Paths II写了一遍。

    class Solution {
    public:
            int uniquePathsWithObstacles(vector<vector<int> >& obstacleGrid) 
            {
                const int m = obstacleGrid.size();
                const int n = obstacleGrid[0].size();
                vector<int> dp(n, 0);
                if ( obstacleGrid[0][0]==1 ) return 0;
                dp[0] = 1;
                for ( size_t i = 0; i < m; ++i )
                {
                    dp[0] = obstacleGrid[i][0]==1 ? 0 : dp[0]; 
                    for ( size_t j =1; j < n; ++j )
                    {
                        dp[j] = obstacleGrid[i][j]==1 ? 0 : dp[j-1] + dp[j];
                    }
                }
                return dp[n-1];
            }
    };

    tips:

    沿用了滚动数组的技巧,额外空间缩减为O(n),代码的效率也提升了。

    ==========================================

    第二次过这道题,用dp过的。

    class Solution {
    public:
        int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
                if (obstacleGrid.empty()) return 0;
                const int m = obstacleGrid.size();
                const int n = obstacleGrid[0].size();
                int dp[m][n];
                fill_n(&dp[0][0], m*n, 0);
                for ( int i=0; i<n; ++i ) 
                {
                    if ( obstacleGrid[0][i]==0 ) 
                    {
                        dp[0][i]=1;
                    }
                    else
                    {
                        break;
                    }
                }
                for ( int i=0; i<m; ++i )
                {
                    if ( obstacleGrid[i][0]==0 )
                    {
                        dp[i][0]=1;
                    }
                    else
                    {
                        break;
                    }
                }
                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];
                        }
                    }
                }
                return dp[m-1][n-1];
        }
    };
  • 相关阅读:
    微信小程序,答题问卷,单选,多选混合在一个借口,前端怎么循环
    react 从0到1
    react从0到0
    es6 系统总结
    点击页面的某个元素,弹出这个元素的索引(是第几个)
    js return的用法
    安装golang.org/x/*
    完美解决从github上下载东西慢的方法
    初探golang和应用其框架 gin 的 使用教程(一)安装篇
    CentOS7安装go开发环境
  • 原文地址:https://www.cnblogs.com/xbf9xbf/p/4532473.html
Copyright © 2020-2023  润新知