題目描述
一個機器人位于一個 m x n 網格的左上角 (起始點在下圖中標記為 “Start” )。
機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為 “Finish” )。
問總共有多少條不同的路徑?
示例 1:
截屏2022-03-18 下午4.37.15.png
輸入:m = 3, n = 7
輸出:28
示例 2:
輸入:m = 3, n = 2
輸出:3
解釋:
從左上角開始,總共有 3 條路徑可以到達右下角
- 向右 -> 向下 -> 向下
- 向下 -> 向下 -> 向右
- 向下 -> 向右 -> 向下
示例 3:
輸入:m = 7, n = 3
輸出:28
示例 4:
輸入:m = 3, n = 3
輸出:6
題解
思路1: 動態規劃
設dp[i][j]為到達點(i,j)的不同路徑數
dp[i][j]的動態轉移方程為
dp[i][j] = dp[i-1][j] + dp[i][j-1] (i>=1,j>=1)
邊界條件:dp[0][0] = 1
也可以將dp[i][0],dp[j][0] 都作為邊界條件,都設為1
// OC
+ (int)uniquePaths1:(int)m n:(int)n {
int dp[m][n];
for (int i=0; i<m; i++) {
dp[i][0] = 1;
}
for (int j=0; j<n; j++) {
dp[0][j] = 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];
}
// Swift
static public func uniquePaths1(_ m:Int, _ n:Int) -> Int {
// dp[i][0] dp[0][j] 都作為邊界條件設為1
if m<1 || n<1 {return 0}
var dp = Array(repeating: Array(repeating: 0, count: n), count: m)
for i in 0..<m {
dp[i][0] = 1
}
for j in 0..<n {
dp[0][j] = 1
}
for i in 1..<m {
for j in 1..<n {
dp[i][j] = dp[i-1][j] + dp[i][j-1]
}
}
return dp[m-1][n-1]
}
思路2:組合數學
從左上角到右下角的過程中,我們需要移動m+n?2 次,其中有m?1 次向下移動,n?1 次向右移動。因此路徑的總數,就等于從m+n?2 次移動中選擇m?1 次向下移動的方案數,即組合數:
C(m+n-2,m-1) = A(m+n-2,m-1)/A(m-1,m-1) = ((m+n-2)(m+n-3)...n) / ((m-1)(m-2)...1)
// OC
+ (int)uniquePaths2:(int)m n:(int)n {
int y = 1;
int x = n;
int ans = 1;
while (y<m) {
ans = (ans * x)/y;
y++;
x++;
}
return ans;
}
// Swift
static public func uniquePaths2(_ m:Int, _ n:Int) -> Int {
if m<1 || n<1 {return 0}
var x=n
var y=1
var ans = 1
while y<m {
ans = (ans * x)/y
y += 1
x += 1
}
return ans
}
參考:https://leetcode-cn.com/problems/unique-paths
https://leetcode-cn.com/problems/unique-paths/solution/bu-tong-lu-jing-by-leetcode-solution-hzjf/