您的位置:首页 > 其它

leetcode 62.不同路径

2018-11-16 12:22 309 查看

题目描述:

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

问总共有多少条不同的路径?

思路 :

从左上角到右下角总共需要走 m+n-2 步,其中 m-1 步向下,剩下的 n-1 步向右。所以这其实是一个简单的排列组合问题...

答案应该是 C( m+n-2 , m-1 ),和与它对称的 C( m+n-2 , n-1 )。挑一个简单的计算就行。时间复杂度应该是O(min(m,n))

[code]int uniquePaths(int m, int n) {
int N=m+n-2;
int M=m<n?m-1:n-1;
//计算 C(N,M)
//根据:C(N,i)=C(N,i-1)*(N-i+1)/i;
//由于是先乘再除的,可能会出现中间结果超出int的情况,所以用long
long ans=1;
for(int i=1;i<=M;i++)
ans=ans*(N-i+1)/i;
return ans;
}

测试运行0ms。

看了一下同样是0ms的其他代码,感觉有点复杂。先去吃午饭再回来琢磨...

//边吃午饭边更新:

假定a[i][j]代表从左上角到 ( i, j ) 格子的路径总数。考虑到能抵达格子( i , j )只有两类方式:1,从它左边走过来;2,从它上面走过来。总路径数,应该是这两类路径数之和。所以 a[i,j] = a[i-1,j] + a[i,j-1]。

[code]int uniquePaths(int m, int n) {
//初始化一个矩阵
int a[m]
{0};
//对于第一行上的格子,只有一条路径:一路向右
for(int i=0;i<n;i++)
a[0][i]=1;
//第一列同理
for(int i=0;i<m;i++)
a[i][0]=1;
//其余格子:a[i][j]=a[i-1][j]+a[i][j-1];
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
a[i][j]=a[i-1][j]+a[i][j-1];
return a[m-1][n-1];
}

注意我用了a[m]
,现在C++里都可以这样了?!

这个算法的时间复杂度是O(m*n),空间复杂度也是O(m*n)。

另外注意到空间还有优化的余地,改进算法如下:

[code]int uniquePaths(int m, int n) {
//初始化一个矩阵
int a
{0};
//第一行
for(int i=0;i<n;i++)
a[i]=1;
//迭代求第i行的值
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
a[j]=a[j]+a[j-1];
return a[n-1];
}

时间复杂度不变,空间优化为O(n)。如果有必要,可以通过调换对行、列的循环顺序,把空间优化为O(min(m,n))。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: