LeetCode-Array-【62】【63】不同路徑(Java)

【62】題目描述

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。

問總共有多少條不同的路徑?
在這裏插入圖片描述

例如,上圖是一個7 x 3 的網格。有多少可能的路徑?

說明:m 和 n 的值均不超過 100。

示例 1:

輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。

  1. 向右 -> 向右 -> 向下
  2. 向右 -> 向下 -> 向右
  3. 向下 -> 向右 -> 向右
    示例 2:

輸入: m = 7, n = 3
輸出: 28

解法:

數學方法:

思路:

根據觀察我們可以知道無論機器人走哪一條路線,機器人都要往下走m-1次,往右走n-1次,因爲機器人走的步數總是m+n-2,令K=m-1;N=m+n-2,因此由排列組合可以知道總路徑爲C(K,N)=n!/(k!(n−k)!)=(n∗(n−1)∗(n−2)∗…(n−k+1))/k!
時間複雜度爲:O(m)

詳細代碼:
class Solution {
    public int uniquePaths(int m, int n) {
        int K = m-1;
        int N = m+n-2;
        long res = 1;
        for(int i = 1 ;i <=K;i++){
            res = res*(N-K+i)/i;
        }
        return (int)res;
    }
}

動態規劃:

思路:

在這裏插入圖片描述
由上圖可知,右下角的數就是總的路徑數。
因此我們令 dp[i][j] 是到達 i, j 最多路徑
動態方程:dp[i][j] = dp[i-1][j] + dp[i][j-1]
注意,對於第一行 dp[0][j],或者第一列 dp[i][0],由於都是在邊界,所以只能爲 1
時間複雜度:O(m*n)O(m∗n)
空間複雜度:O(m * n)O(m∗n)
優化:因爲我們每次只需要 dp[i-1][j],dp[i][j-1]

詳細代碼:
class Solution {
    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for(int i = 0 ; i < n;i++)    dp[0][i]=1;
        for(int i = 0 ; i < m;i++)      dp[i][0]=1;
        for(int i =1;i<m;i++){
            for(int j = 1;j<n;j++){
                dp[i][j] = dp[i-1][j]+dp[i][j-1];
            }
        }
        return dp[m-1][n-1];
    }
}

【63】、題目描述

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。

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

在這裏插入圖片描述
網格中的障礙物和空位置分別用 1 和 0 來表示。

說明:m 和 n 的值均不超過 100。

示例 1:

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

  1. 向右 -> 向右 -> 向下 -> 向下
  2. 向下 -> 向下 -> 向右 -> 向右
解法:

動態規劃:

思路分析:
  • 此題跟上面的第一題差不多,都是涉及到動態規劃和數學思想解題,首先我們先明確動態方程: value[i][j] =
    value[i-1][j]+value[i][j-1];注意:本題與上題唯一的不同之處在於在路徑上有障礙物,那麼我們只需要將有障礙物的路徑value值置爲0即可,另外,本題的第一行和第一列value值與上題的賦值方式不同,我們需要先判斷該位置是有障礙物,如果有,那麼其右邊,或者下邊的value值都爲0;
  • 採用動態規劃的時間複雜度爲:O(m*n);
詳細代碼:
class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        if(obstacleGrid[0][0]==1) return 0;
        int[][] value = new int[m][n];
        value[0][0]=1;
        for(int i = 1;i<n;i++){
            if(obstacleGrid[0][i]!=1){
                value[0][i] = value[0][i-1];
            }
        }
        for(int i = 1;i<m;i++){
            if(obstacleGrid[i][0]!=1){
                value[i][0] = value[i-1][0];
            }
        }
        for(int i = 1;i<m;i++){
            for(int j =1;j<n;j++){
                if(obstacleGrid[i][j]!=1){
                    value[i][j] = value[i-1][j]+value[i][j-1];
                }
            }
        }
        return value[m-1][n-1];
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章