【62】題目描述
一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記爲“Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記爲“Finish”)。
問總共有多少條不同的路徑?
例如,上圖是一個7 x 3 的網格。有多少可能的路徑?
說明:m 和 n 的值均不超過 100。
示例 1:
輸入: m = 3, n = 2
輸出: 3
解釋:
從左上角開始,總共有 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 條不同的路徑:
- 向右 -> 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右 -> 向右
解法:
動態規劃:
思路分析:
- 此題跟上面的第一題差不多,都是涉及到動態規劃和數學思想解題,首先我們先明確動態方程: 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];
}
}