原题如下:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。问总共有多少条不同的路径?
例如,上图是一个7 x 3 的网格。有多少可能的路径?
说明:m 和 n 的值均不超过 100。
通过分析我们可以发现 机器人很笨,它只会向右或者下走,也就是说它如果向右走,左边的格子就回不去了 自己的活动范围被缩小(如果向下走的话 上面的格子就回不去了)。所以在每个格子上都有两种情况:向右或者向下,也就是说 我们求得向右走获得的路线数x,向下走获得的路线数y,x+y 即为总路线数。
BUT ## 这也仅仅局限于m*n的规模比较小的情况!!!当m=n=100的时候每个格子都有两种情况,计算两种情况的时间巨高(两种情况下又不知道有多少情况)。。。
这时候需要思考,我们是否有必要把每个格子的两种情况都考虑进去。此外,走到每个格子的路线跳数一定是唯一的!!!规模庞大的我们很难知道,但是规模较小的却很容易得到,能否利用规模较小的结果退出规模大一点的结果???
就m=7 n=3 而言(这里m为列!n为行!)
1 1 1 1 1 1 1(如果仅仅只有一行 那么到哪个格子都只有一条路线)
1 2 3 4 5 6 7 (写到这里可能还不容易发现什么规律)
1 3 6 10 15 21 28 (写到最后一行规律就很明显了)
就m[ i ][ j ]而言 它等于x=m[ i ][j-1 ] , y=m[ i-1 ][ j ] 相加(和上面递归的方法思想类似)
以下是两个方法的代码(递归方法时间复杂度太高)
class Solution {
public:
int digui_qiu(int m,int n){
int total = 0;
if (n <= 0 || m <= 0) return 0;
if (m == 1 && n == 1) return 1;
total+= digui_qiu(m, n - 1);//如果向右走
total+=digui_qiu(m-1,n);//如果向下走
return total;
}
int dongtai_guihua(int m, int n){
vector <vector<int>>total(m);
for (int i = 0; i <= total.size() - 1; i++) total[i].resize(n);
total[0][0] = 1;
for (int j = 1; j <= total[0].size() - 1; j++)
total[0][j] = 1;
for (int i = 1; i <= total.size() - 1; i++)
total[i][0] = 1;
for (int i = 1; i <= total.size() - 1; i++){
for (int j = 1; j <= total[i].size() - 1; j++)
total[i][j] = total[i - 1][j] + total[i][j - 1];
}
return total[m - 1][n - 1];
}
int uniquePaths(int m, int n) {
// int tmp= digui_qiu(n, m);
int tmp = dongtai_guihua(n, m);
cout << tmp << endl;
return tmp;
}
};