62. 不同路径
题目描述:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
解题思路1:
动态规划的三个步骤:
1. 定义数组元素的含义;创建一个二维数组sig[m][n]
2. 找出数组之间的关系;
想象以下,机器器⼈人要怎么样才能到达 (i, j) 这个位置?由于机器人可以向下⾛走或者向右⾛走,所以有两种⽅式到达;
一种是从 (i-1, j) 这个位置⾛走⼀一步到达;一种是从(i, j - 1) 这个位置走⼀步到达;
因为是计算所有可能的步骤,所以是把所有可能⾛走的路路径都加起来,所以关系式是 dp[i] [j] = dp[i-1] [j]+ dp[i] [j-1]
3. 找出初始值;
dp[0] [0….n-1] = 1; // 相当于最上⾯面⼀⾏行,机器器人只能一直往左⾛;
dp[0…m-1] [0] = 1; // 相当于最左⾯面⼀列列,机器器人只能一直往下⾛。
1 class Solution { 2 public: 3 int uniquePaths(int m, int n) 4 { 5 //int sig[m][n]; 6 /* 动态创建一个二维数组,考虑内存释放,否则会泄露*/ 7 int** sig=new int* [m]; 8 for(int i=0;i<m;i++) 9 { 10 sig[i]=new int[n]; 11 } 12 13 for (int i=0; i<m; i++) 14 { 15 sig[i][0]=1; 16 } 17 for (int i=0; i<n; i++) 18 { 19 sig[0][i]=1; 20 } 21 22 for (int i=1; i<m; i++) 23 for (int j=1; j<n; j++) 24 { 25 sig[i][j] = sig[i-1][j] + sig[i][j-1]; 26 } 27 return sig[m-1][n-1]; 28 } 29 };
解题思路1:优化
注意一维二维和三维数组的动态内存分配;
1 //一维数组动态内存分配 2 int *dp = (int *)malloc(sizeof(int) * n); 3 4 int* dp = new int[n]; 5 6 7 // 二维数组动态申请,b数组大小为: n*p 8 int **b = new int*[n]; 9 for(int i=0; i<n; i++) 10 { 11 b[i] = new int[p]; 12 } 13 14 // 三维数组动态申请, c数组大小为: m*n*p: 15 int ***c = new int **[m]; 16 for(int i=0; i<m; i++) 17 { 18 c[i]=new int *[n]; 19 for(int j=0; j<n; j++) 20 { 21 c[i][j] = new int [p]; 22 } 23 }
用一维数组代替二维数组,省去了很多无需保存的数据。
1 class Solution { 2 public: 3 int uniquePaths(int m, int n) 4 { 5 //std::vector<int> dp(n); 6 //int *dp = (int *)malloc(sizeof(int) * n); 7 //一维数组动态申请,a数组大小为: n 8 int* dp = new int[n]; 9 10 if (m <= 0 || n <= 0) 11 { 12 return 0; 13 } 14 15 for (int i=0; i<n; i++) 16 { 17 dp[i] = 1; 18 } 19 20 for (int i=1; i<m; i++) 21 { 22 dp[0] = 1; 23 for (int j=1; j<n; j++) 24 { 25 dp[j] = dp[j-1] + dp[j]; 26 } 27 } 28 return dp[n-1]; 29 } 30 };