[LeetCode刷题] 62.不同路径–Java实现
刷题汇总
题目链接
https://leetcode-cn.com/problems/unique-paths/
题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
示例 1:
输入: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 <= m, n <= 100
题目数据保证答案小于等于 2 * 109
解题思路
1.动态规划
题目要求从网格的左上角走到网格的右下角,每次只能往下或往右前进一个。假设一个m * n的网格,若是往右走一步,则剩下的问题可看做是(m-1) * n的网格,同理,若是往下走一步,则剩下的问题可看做是m * (n-1)的网格。
因此我们可以写出递归关系:f(i, j) = f(i-1, j) + f(i, j-1)
最终可以递归到1*1的网格,只有1个路线。
时间复杂度:O(mn),空间复杂度:O(mn)。
Java代码实现:
class Solution {
public int uniquePaths(int m, int n) {
if (m==1|| n==1) return 1;
//新建一个二维数组
int[][] arr = new int[m+1][n+1];
//循环遍历
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
//给边界赋值
if(i==1) arr[i][j] = 1;
//给边界赋值
else if(j==1) arr[i][j] = 1;
//其余网格累加
else arr[i][j] = arr[i-1][j] + arr[i][j-1];
}
}
//输出结果
return arr[m][n];
}
}
2.递归(会超出时间限制)
递归和动态规划思路大体相同,只是解决手段不同。
上面的方法中采用了一个二维数组去模拟实际过程中网格的前进位置。
递归的方法比较简单,不断的调用自身,直到迭代到m=1,n=1,并逆向累加,最后输出结果。这个方法虽然代码简单,但因为不断的调用自身,花费较长的时间,会超出力扣的判题时间限制。
Java代码实现:
class Solution {
public int uniquePaths(int m, int n) {
if(m==1 && n==1)
return 1;
if(m==1)
return uniquePaths(m,n-1);
if(n==1)
return uniquePaths(m-1,n);
return uniquePaths(m-1,n) + uniquePaths(m,n-1);
}
}