力扣-动态规划-62. 不同路径
62. 不同路径
题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
示例 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
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路:动态规划
今天接着刷第三道动态规划的题目,在正式开始做题之前我们来捋一下dp的思路,动态规划思路:
1.确定dp数组及下标的含义,本题要求的是路径的数量,并且是m*n的表格,那么dp(m,n)就代表从起点到(m,n)位置路径的数量。
2.确定状态转移方程,也就是递推公式。动态规划的特点是前面的决策会影响到后面的决策,也就是前面不同的决策会影响后面的结果。本题中到达终点只有两个方向,从终点的上方或者左方,再结合举例推导得到的规律,可以推出递推公式为:dp(m,n) = dp(m - 1,n) + dp(m,n - 1);
3.dp数组初始化,通过分析知道当m=1或者n=1时,dp(m,n) = 1;
4.遍历顺序,dp第一行所有列已经初始化为1,第一列也全部初始化为1。结合表格图可以知道当前位置的路径数量是有同一行的上一列和同一列的上一行dp值相加得到,因此遍历顺序是每一行依次从左到右。
5.举例推导dp,与代码结果比较。
在知道这道题需要用动态规划解决的情况下,解决本题比较麻烦的地方在于推导状态转移方程,我是先举了几个例子,然后寻找数字之间的规律,有种找规律的感觉。后来提交之后研究题解,才发现找规律其实也是可以结合题目特点,本题到达终点只有两个方向:从终点的左方或者上方,终点的左方就是行不变列减1,上方就是列不变行减1,因为是并列关系,所以直接相加。
我自己写的代码如下,代码已经加了注释,各位小伙伴如果有什么问题可以在评论里提出来,欢迎大家交流。
//动态规划 前面的状态会影响到后面的决策
//动态规划也是要寻找最优解,在前面的决策也要考虑最优选择,但和贪心不同的是,贪心前面的选择可以跟后面分开进行,前面的选择不会影响后面的决策。
//自己的思路
//动态规划
public int uniquePaths(int m, int n) {
//1.dp[m,n]代表 m*n 网格所有的不同路径数量
//2.状态转移方程 dp[m,n] = dp[m - 1,n] + dp[m,n - 1]
//3.初始化 m=1或者n=1,dp[m,n] = 1;m = 2,n = 2,dp[m,n] = 2.
//4.遍历顺序 依次递减m和n,直到满足初始化的条件
//5.举例推导
if (m == 1 || n == 1) {
return 1;
}
if (m == 2 && n == 2) {
return 2;
}
int[] dp = new int[n + 1];
for (int i = 1; i <= n; i++) {
dp[i] = 1;
}
for (int i = 2; i <= m; i++) {
for (int j = 2; j <= n; j++) {
dp[j] += dp[j - 1];
}
}
return dp[n];
}
另外附上我自己搭建的个人博客网址,里面记录了我之前记录的学习心得,欢迎大家交流讨论。