携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情
题目:LeetCode 【难易度:中等】
一个机器人位于一个 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 * 10^9
解题思路
分析题目就可知,就是求不同路径的最大数目,那首先想到的是动态规划问题。但其实也有另外的方法来解决-递归法。
解题的关键就是要找出 递归关系式。定义一个函数 dfs(i,j)表示从(0,0)到(i,j)的所有路径数,根据题目提示中的图结合上面设定分函数dfs(i,j),要到达(i, j)这个位置,会有以下两种方式:
- 从 (i-1, j) 位置走一步到达
- 从(i, j – 1) 位置走一步到达
那么推算出来递推关系式:dfs(i, j) = dfs(i – 1, j) + dfs(i, j – 1),
接下来就是确定初始值,根据上面推算的递推关系 在dfs(i, j)中如果i=0 或者 j=0,那递推关系就不成立。公式中的i-1或j-1就会出现负数,结合问题场景可以知道i=0或j=0 就是函数边界,此时dfs(i, j) = 1。
但再进一步分析:dfs(i, j) = dfs(i – 1, j) + dfs(i, j – 1) 关系式算出来的有存在重复数据。举例示范一下:(i =4, j=4)时
可以看到红线圈出来的数据是存在重复情况的,因此用变量要存起来,每次都要判断一下来确保位置是否已存在数据。
代码分析
class Solution {
// 全局变量,定义二维数组来保存计算好的值
static int[][] arr = null;
public int uniquePaths(int m, int n) {
// 创建一个二维数组
arr = new int[m][n];
return dfs(m - 1, n -1);
}
public int dfs(int i, int j) {
if(i == 0 || j == 0){
return 1;
}
// java 中,数组的初始值是 0,所以可以用 arr[i][i] 是否为 0 来判断
if(arr[i][j] != 0){
return arr[i][j];
}
// 把计算过的值保存起来
arr[i][j] = dfs(i - 1, j) + dfs(i, j - 1);
return arr[i][j];
}
}
这题的主要关键点是找出递推关系和初始值,其余元素就可以被推导出来。
在掘金(JUEJIN) 一起分享知识, Keep Learning!