一个机器人位于一个 m x n
网格的左上角 (起始点在下图中标记为 “Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。
问总共有多少条不同的路径?
输入: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
动态规划解决问题
思路:当看到此题有多少种不同的路径且他用了二维数组的形似,就相当了dp数组,可能用到动态规划的思路。
确定动态规划的五部曲
题目的意思是只能从左往右走。或者从上往下走。
1.确定dp数组的含义:这里的dp数字就代表到达每个格子的路径有多少种。
2.确定递推公式:dp[ i ][ j ] = dp[ i ][ j-1 ]+dp[ i-1 ][ j ] 。解释因为每一个格子到达的路径的个数,就等于他正上方的格子路径的个数加上他正左边格式路径的个数。
3.dp数组的初始化: dp[i][0] = 1 dp[0][j] = 1。 因为第一行和第一列中的每一个格子,到达的路径只能有一条、
4.确定遍历的顺序:这道题很容易顺序思维就是从左到右,从上到下遍历dp数组。
5.遍历dp数组:一般遍历dp数组可以帮助我们验证思路,返回的结果是否正确。一个验证的作用
class Solution {
public:
int uniquePaths(int m, int n) {
//定义dp数组
vector<vector<int>> dp(m,vector<int>(n,0));
//初始化dp数组
for(int i = 0;i<n;i++){dp[0][i] = 1;}
for(int j = 0;j<m;j++){dp[j][0] = 1;}
for(int i=1;i<m;i++)
{
for(int j = 1;j<n;j++)
{
//递推公式
dp[i][j] = dp[i][j-1]+dp[i-1][j];
//遍历打印
cout<<"dp["<<i<<"]["<<j<<"]="<<dp[i][j]<<endl;
}
}
return dp[m-1][n-1];
}
};
时间复杂度O(N*M)
空间复杂度O(N*M)
因为遍历dp数组,以及开辟dp数组所需要的额外空间都是n*m的复杂度。当然此题可以用深搜或者图论来做,图论做超时了。