【每日一題】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];
    }
};

如果有問題,歡迎大家指正!!!

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