Question
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).

The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).

How many possible unique paths are there?


本题难度Medium。有3种算法分别是:DFS、DP和一维数组(DP优化版)

1、DFS

【复杂度】
时间 O(N!) 空间 O(1)

【思路】
利用DFS遍历所有可能。不过这个方法会 Time Limit Exceeded。

【注意】
23行​​​helper(x+1,y,m,n);​​不要写成:

helper(++x,y,m,n);

它会影响25行。

【代码】

public class Solution {
int count=0;
public int uniquePaths(int m, int n) {
//require
if(m==0||n==0)
return 1;
if(m==1||n==1)
return 1;
//invariant
helper(0,0,m,n);
//ensure
return count;
}

private void helper(int x,int y,int m,int n){
//base case
if(x==m-1||y==n-1){
count++;
return;
}

if(x<m-1)
helper(x+1,y,m,n);
if(y<n-1)
helper(x,y+1,m,n);
}
}

2、DP

【复杂度】
时间 O(MN) 空间 O(MN)

【思路】
每一步只能向右方或者下方走,所以经过每一个格子路径数只可能源自左方或上方,这就得到了动态规划的递推式,我们用一个二维数组dp储存每个格子的路径数,则​​​dp[i][j]=dp[i-1][j]+dp[i][j-1]​​。最左边和最上边的路径数都固定为1,代表一直沿着最边缘走的路径。

【附】
本题的测试用例中应该没有​​​m=0,n=0​​。

【代码】

public class Solution {
public int uniquePaths(int m, int n) {
//require
int[][] dp=new int[m][n];
for(int i=0;i<m;i++)
dp[i][0]=1;
for(int i=0;i<n;i++)
dp[0][i]=1;
//invariant
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
dp[i][j]=dp[i-1][j]+dp[i][j-1];
//ensure
return dp[m-1][n-1];
}
}

3、一维数组

【复杂度】
时间 O(MN) 空间 O(N)

【思路】
实际上我们可以复用每一行的数组来节省空间,每个元素更新前的值都是其在二维数组中对应列的上一行的值。这里​​​dp[i] = dp[i - 1] + dp[i]​

【注意】
dp[0]一直等于1,因此8行的​​​i​​​与9行的​​j​​​都是从​​1​​​而不是​​0​​开始循环。

【代码】

public class Solution {
public int uniquePaths(int m, int n) {
//require
int[] dp=new int[n];
for(int i=0;i<n;i++)
dp[i]=1;
//invariant
for(int i=1;i<m;i++)
for(int j=1;j<n;j++)
dp[j]=dp[j]+dp[j-1];
//ensure
return dp[n-1];
}
}

参考

​​[Leetcode] Unique Paths 唯一路径​​