Unique Paths
机器人在最左上角,它只能向右和向下走,找出所有的独一无二的路径,使它能达到最右下角位置。
对已这个题我首先的思路是递归,因为机器人只能向下和向右走,所以将下和右方向的路径加起来就行了,代码也清晰明了,代码如下,想法是好的,可是现实是残酷的,时间复杂度不够。
class Solution { public: int uniquePaths(int m, int n) { if (m == 1 || n == 1) { return 1; } return FindAllUniqPath(0, 0, m - 1, n - 1); //return FindAllUniqPath(1, 0, m-1, n-1) + FindAllUniqPath(0,1,m-1,n-1); } int FindAllUniqPath(int x, int y, int endx, int endy) { // if (x == endx || y == endy) { return 1; } return FindAllUniqPath(x + 1, y , endx, endy) + FindAllUniqPath(x,y+1,endx,endy); } };
没办法,这路不通,这种递归的思路行不通,得另辟蹊径。我仔细观察加画图,我发现其实这算是个数字规律吧,我来解释一下这个数字规律吧:
所以我的解题思路还是从数学规律出发,找大可以复用的部分,然后用循环解决问题,具体复用的防方法,请结合上面的图的分析加上自己的思索,然后就可以找出规律了,下面我就给出正确的代码,大家可以参考一下。
class Solution { public: int uniquePaths(int m, int n) { //m和n都是在[1,100]之间 assert(m <= 100); assert(n <= 100); if (m == 1 || n == 1) { return 1; } //第一行,最后一列 int sum = 1; vector<int> v1(m, 0); vector<int> v2(m, 1); int end = n - 1; while (end > 0) { int tmp = 0; //每次更新v1 v1 = v2; for (int i = 1; i < m; ++i) { tmp += v1[i]; } //得到本次(一列)所有的独一无二的路径的数目 sum += tmp; //得到前面一列中各个点所能得到的独一无二的路径的数目,注意从底部往上找的话,可以去掉冗余部分的 int total = 0; for (int i = m - 1; i > 0; --i) { //更新前面一列各个点的所对应的路径数目 total += v1[i]; v2[i] = total; } --end; } return sum; } };
最终程序的结果如下,验证其正确性。
时间: 2024-10-05 21:32:37