【每日一题】LeetCode. 63. 不同路径Ⅱ

每日一题,防止痴呆 = =

一、题目大意

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
在这里插入图片描述
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-ii

二、题目思路以及AC代码

思路

这题我一开始傻傻的想到dfs,可能是反应,看到地图就想dfs和bfs = =,然后也没考虑时间复杂度就写了,结果不出意料的TLE。

然后抛开dfs的思路,再一看,好像就是很明显的动态规划,只需要设dp[i][j]表示从(i, j)处到达终点的路径条数就可以了,递推公式如下:
dp[i][j] = obstacleGrid[i][j] ? 0 : dp[i+1][j] + dp[i][j+1]

这里注意到我们其实在计算dp[i][j]的时候,只用到了它下面和右边的元素,所以可以用滚动数组进行优化,将空间复杂度优化为O(cols),cols是列数

AC代码

最开始傻傻的dfs方法,写了就别浪费

class Solution {
private:
    int ex, ey;
    int* dx;
    int* dy;

    bool** vis;
public:
    int dfs(vector<vector<int>>& obstacleGrid, int x, int y) {
        if (x == ex - 1 && y == ey - 1) return obstacleGrid[x][y] ? 0 : 1;

        int res = 0;
        for (int i=0;i<2;i++) {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx >= ex || ny >= ey || vis[nx][ny] || obstacleGrid[nx][ny]) continue;
            vis[nx][ny] = true;
            res += dfs(obstacleGrid, nx, ny);
            vis[nx][ny] = false;
        }
        
        return res;
    }

    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        dx = new int[2];
        dy = new int[2];
        dx[0] = 1; dx[1] = 0;
        dy[0] = 0; dy[1] = 1;

        ex = obstacleGrid.size();
        ey = obstacleGrid[0].size();
        vis = new bool*[ex];
        for (int i=0;i<ex;i++) vis[i] = new bool[ey];
        for (int i=0;i<ex;i++) {
            for (int j=0;j<ey;j++) {
                vis[i][j] = false;
            }
        }

        return obstacleGrid[0][0] ? 0 : dfs(obstacleGrid, 0, 0);
    }
};

动态规划:

class Solution {
public:
    int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) {
        int rows = obstacleGrid.size();
        int cols = obstacleGrid[0].size();

        long long dp[cols];
        dp[cols-1] = obstacleGrid[rows-1][cols-1] ? 0 : 1;
        for (int i=cols-2;i>=0;i--) {
            dp[i] = obstacleGrid[rows-1][i] ? 0 : dp[i+1];
        }
        for (int i=rows-2;i>=0;i--) {
            for (int j=cols-1;j>=0;j--) {
                if (j == cols - 1) dp[j] = obstacleGrid[i][j] ? 0 : dp[j];
                else dp[j] = obstacleGrid[i][j] ? 0 : dp[j] + dp[j+1];
            }
        }

        return dp[0];
    }
};

如果有问题,欢迎大家指正!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章