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
分析:
- 面对这道算法题目,二当家的再次陷入了沉思。
- 每一个点的不同路径数是到达上面点的不同路径数与到达左面不同路径数的和。所以可以考虑动态规划,第一行因为只能向右移动,所以不同路径数都是1,同样第一列也是如此,只能向下移动,所以不同路径数也是1。
- 动态规划很直观,但是需要双循环。还可以考虑转化为数学问题,知道了行列数,所以一共向右和向下移动的步数是已知条件,我们能选择的只是向右移动和向下移动的顺序。有
m
行,和n
列,所以需要向右移动m - 1
次,向下移动n - 1
次,总共移动m + n - 2
次,所以相当于是从m + n - 2
移动中选择m - 1
次向右移动(与从m + n - 2
移动中选择n - 1
次向下移动值相等),转化为了组合数问题。
题解:
rust:
impl Solution {
pub fn unique_paths(m: i32, n: i32) -> i32 {
let (m, n) = (m.min(n) as u64, m.max(n) as u64);
(1..m).fold(1, |ans, y| ans * (y + n - 1) / y) as i32
}
}
go:
func uniquePaths(m int, n int) int {
return int(new(big.Int).Binomial(int64(m+n-2), int64(n-1)).Int64())
}
c++:
class Solution {
public:
int uniquePaths(int m, int n) {
long long ans = 1;
for (int x = n, y = 1; y < m; ++x, ++y) {
ans = ans * x / y;
}
return ans;
}
};
python:
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
return comb(m + n - 2, n - 1)
java:
class Solution {
public int uniquePaths(int m, int n) {
long ans = 1;
for (int x = n, y = 1; y < m; ++x, ++y) {
ans = ans * x / y;
}
return (int) ans;
}
}
非常感谢你阅读本文~
欢迎【点赞】【收藏】【评论】三连走一波~
放弃不难,但坚持一定很酷~
希望我们大家都能每天进步一点点~
本文由 二当家的白帽子:https://le-yi.blog.csdn.net/ 博客原创~