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;
}
};
最终程序的结果如下,验证其正确性。