一、题目描述
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?


二、解题思路
解题思路一
机器人从(0,0)位置出发,到(m-1,n-1)是终点。
按照动规五部曲:
第一步:确定dp数组(dp table)以及下标的含义
dp[i][j]表示从(0 ,0)出发,到(i, j) 有dp[i][j]条不同的路径。
第二步:确定递归公式
想要求dp[i][j],只能有两个⽅向来推导出来,即dp[i-1][j]和 dp[i][j - 1]。
此时在回顾⼀下 dp[i-1][j]表示啥,是从(0, 0)的位置到(i - 1, j)有⼏条路径,dp[i][j - 1]同理。
那么很⾃然,dp[i][j] = dp[i-1][j] + dp[i][j-1],因为dp[i][j]只有这两个⽅向过来。
第三步:dp数组初始化
如何初始化呢,⾸先dp[i][0]⼀定都是1,因为从(0, 0)的位置到(i, 0)的路径只有⼀条,那么dp[0][j]也同理。
所以初始化代码为:
for (int i = 0; i < m; i++) dp[i][0] = 1;
for (int j = 0; j < n; j++) dp[0][j] = 1;
第四步:确定遍历顺序
这⾥要看⼀下递归公式dp[i][j] = dp[i - 1][j] + dp[i][j - 1],dp[i][j]都是从其上⽅和左⽅推导⽽来,那么从左到右⼀层⼀层遍历就可以了。
这样就可以保证推导dp[i][j]的时候,dp[i-1][j]和 dp[i][j-1]⼀定是有数值的。
第五步:举例推导dp数组
如图所示:

代码演示一:
class Solution {
public int uniquePaths(int m, int n) {
//声明一个二维数组,用来存储路径数
int[][] dp = new int[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];
}
}
时间复杂度:O(m*n)
空间复杂度:O(m*n)
解题思路二
看下面图,可以看出一共m,n的话无论怎么走,走到终点都需要m+n-2步:

在这m+n-2步中,一定有m-1步是要向下走的,n-1步向右走,不管什么时候走,怎么走,总的步数是不变的,所以这就变成了一个排列组合问题,转换成总共要走m+n-2步,往下走m-1步有多少中走法。公式如下:

排列组合计算公式:

本题公式为: (m+n-2)! / [(m-1)! * (n-1)!]
代码演示二:
class Solution {
public int uniquePaths(int m, int n) {
//总的结果数
int N = n + m - 2;
double res = 1;
for (int i = 1; i < m; i++){
//注意这里的计算分析
res = res * (N - (m - 1) + i) / i;
}
return (int) res;
}
}
时间复杂度:O(m)
空间复杂度:O(1)
这里分析一下为什么res = res * (N - (m - 1) + i) / i:
比如要计算:n!/(n-m)! ,那么可以把(n-m)!约掉【这里的m 、n与题无关】
相当于在n的阶乘中,后面的1 ~ n-m没了,只把n-(m+1)到n乘起来。
n! = n * (n-1) * (n-2) * ··· * (n-(m+1)) * (n-m) * (n-(m-1)) * ···* 3 * 2 * 1
然后后半段被约掉了: n * (n-1) * (n-2) * ··· * (n-(m+1)) *【 (n-m) * (n-(m-1)) * ···* 3 * 2 * 1】
只剩下: n * (n-1) * (n-2) * ··· * (n-(m+1))
这篇博客探讨了如何解决一个机器人在网格中找到到达终点不同路径的问题。首先介绍了动态规划(DP)的五步法来解决此问题,通过初始化dp数组并逐层遍历计算每个位置的路径数。其次,提出了一种使用排列组合的思路,将问题转化为计算特定步数的排列数。两种方法分别提供了时间复杂度为O(m*n)和O(m)的解决方案,并给出了相应的Java代码实现。
913

被折叠的 条评论
为什么被折叠?



