62. 不同路徑——動態規劃/排列組合
阿新 • • 發佈:2021-01-28
技術標籤:# LeetCode HOT 100動態規劃演算法c++資料結構python
1.題目
62. 不同路徑
一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為 “Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為 “Finish” )。
問總共有多少條不同的路徑?
示例 1:
輸入:m = 3, n = 7
輸出:28
示例 2:
輸入:m = 3, n = 2
輸出:3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角。
1. 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右
3. 向下 -> 向右 -> 向下
示例 3:
輸入:m = 7, n = 3
輸出:28
示例 4:
輸入:m = 3, n = 3
輸出:6
提示:
1 <= m, n <= 100
題目資料保證答案小於等於 2 * 109
2.自我思路及實現
3.總結思路及實現
動態規劃
設f(i,j)代表走到i,j處的所有路徑,那麼機器人或者向下到達i,j,或者向右到達i, j,那麼狀態轉移方程就是:
f (i , j) = f ( i − 1 , j ) + f ( i , j − 1)
上述方程i, j 不等於0
特例
- 當i或 j = 0,時,只有一種路徑可以到達
- f(0,0) = 1
優化:
- 由於結果只與上一行和本行有關,因此可以建立一個一維陣列來儲存結果
- cur[j] = cur[j - 1] + cur[j]
- 未賦值之前右邊的cur[j] 始終表示當前行第i行的上一行第j列的值,賦值之後左邊的cur[j]表示當前行第i行第j列的值,cur[j-1] 表示當前行第i行第j-1列的值(cur[j-1] 在計算cur[j]之前就已經計算了,所以表示的是當前行而不是上一行
時間:mn
空間:min(m ,n)
class Solution {
public int uniquePaths(int m, int n) {
if(m > n)
return uniquePaths(n, m);
int[] cur = new int[n];
Arrays.fill(cur, 1);
for(int i = 1; i < m; i++)
{
for(int j = 1; j < n; j++)
{
cur[j] += cur[j - 1];
}
}
return cur[n - 1];
}
}
排列組合
無論哪種路徑,總是向下移動m - 1次,向右移動n-1次,那麼問題轉化為
m - 1個a與n - 1個b共有多少種排列方式
根據排列組合計算,在 m - 1 + n - 1個位置中找m個位置將a放入,其餘位置填上b
C下(m - 1 + n - 1),上( m - 1) 或(n - 1)
化簡為
為了防止乘法時越界,使用long儲存結果
時間:min(m, n),與迴圈次數有關,我們總可以選擇m為較小的數
空間:1
class Solution {
public int uniquePaths(int m, int n) {
if(m > n)
return uniquePaths(n, m);
long ans = 1;
for (int x = n, y = 1; y <= m - 1; x++, y++) {
ans = ans * x / y;
}
return (int) ans;
}
}