1. 程式人生 > 其它 >關於微擎2.7.8不帶網路控制檯自定義路由修改方法

關於微擎2.7.8不帶網路控制檯自定義路由修改方法

63. 不同路徑 II

題目連結: 63. 不同路徑 II(中等)

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為 “Start” )。機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為 “Finish”)。

現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?

網格中的障礙物和空位置分別用 10 來表示。

示例 1:

輸入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
輸出:2
解釋:3x3 網格的正中間有一個障礙物。
從左上角到右下角一共有 2 條不同的路徑:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

示例 2:

輸入:obstacleGrid = [[0,1],[0,0]]
輸出:1

提示:

  • m == obstacleGrid.length

  • n == obstacleGrid[i].length

  • 1 <= m, n <= 100

  • obstacleGrid[i][j]01

解題思路

62. 不同路徑類似,都可以採用動態規劃解決。

  1. 確定dp陣列以及其下標的含義

    該題的dp陣列是一個二維陣列。dp[i,j]表示從(0,0)出發到(i,j)的路徑數

  2. 確定遞推公式

    題目中表示每一步只能向下或向右移動,所以要走到 (i,j)處,只能從從(i,j-1)處向下走一步或從(i-1,j)

    處向右走一步。所以可以得到遞推公式: dp[i,j] = dp[i,j - 1] + dp[i - 1,j]。但是需要注意,如果 (i,j)處有障礙,那dp[i,j] = 0

  3. dp陣列的初始化

    (0, 0)(i, 0)的路徑只有一條,所以dp[i,0] = 1,但如果(i, 0)處有障礙,那(i, 0)及後面的初始值都為0(如下圖所示),dp[0,j]同理。

  4. 確定遍歷順序

    由遞推公式可以看出dp[i,j]是由其上方和其左方推到出來的,所以遍歷順序是從左到右一層一層地遍歷的

  5. 舉例推導dp陣列

    在例1中,可以得到的dp陣列如下所示

C++

class Solution {
public:
    
// 將obstacleGrid陣列直接轉為dp陣列 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m = obstacleGrid.size(); int n = obstacleGrid[0].size(); for (int i = 0; i < m; i++) { if (obstacleGrid[i][0] == 0) { //表示當前位置無障礙 if (i > 0 && obstacleGrid[i - 1][0] == 0) { //表示當前位置的左邊有障礙(已經從1變為了0) obstacleGrid[i][0] = 0; } else obstacleGrid[i][0] = 1; } else if (obstacleGrid[i][0] == 1) { //表示當前位置有障礙 obstacleGrid[i][0] = 0; } } for (int j = 1; j < n; j++) { if (obstacleGrid[0][j] == 0) { //表示當前位置無障礙 if (j > 0 && obstacleGrid[0][j - 1] == 0) { //表示當前位置的左邊有障礙(已經從1變為了0) obstacleGrid[0][j] = 0; } else obstacleGrid[0][j] = 1; } else if (obstacleGrid[0][j] == 1) { //表示當前位置有障礙 obstacleGrid[0][j] = 0; } } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { if(obstacleGrid[i][j] == 1) obstacleGrid[i][j] = 0; else obstacleGrid[i][j] = obstacleGrid[i - 1][j] + obstacleGrid[i][j - 1]; } } return obstacleGrid[m - 1][n - 1]; } }; ​ class Solution1 { public: // 重新定義dp陣列並全部初始化為0 int uniquePathsWithObstacles(vector<vector<int>>& obstacleGrid) { int m = obstacleGrid.size(); int n = obstacleGrid[0].size(); vector<vector<int>> dp(m, vector<int>(n, 0)); for (int i = 0; i < m && obstacleGrid[i][0] == 0; i++) dp[i][0] = 1; for (int j = 0; j < n && obstacleGrid[0][j] == 0; j++) dp[0][j] = 1; for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { if (obstacleGrid[i][j] == 1) continue; else dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } return dp[m - 1][n - 1]; } };

JavaScript

/**
 * @param {number[][]} obstacleGrid
 * @return {number}
 */
var uniquePathsWithObstacles = function(obstacleGrid) {
    let m = obstacleGrid.length;
    let n = obstacleGrid[0].length;
    const dp = Array(m).fill().map(item => Array(n).fill(0));
​
    for (let i = 0; i < m && obstacleGrid[i][0] === 0; i++) dp[i][0] = 1;
    for (let j = 0; j < n && obstacleGrid[0][j] === 0; j++) dp[0][j] = 1;
​
    for (let i = 1; i < m; i++) {
        for (let j = 1; j < n; j++) {
            if (obstacleGrid[i][j] === 1) continue;
            else dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        }
    }
​
    return dp[m - 1][n - 1];
};

時間複雜度:O(m × n)

空間複雜度:O(m × n)