一、问题描述
- 给定一个m*n矩阵,起点位于[0,0]位置,终点位于[m-1.n-1],并且只能向右或者向下走,求从起点到终点共有多少种行走方式
- 如图所示:
二、解题思路
- 使用回溯算法,在每一个位置都最多有两种走法,依次计算从该位置走到目的地的次数。如果m,n较大,会导致超时。
- 使用动态规划算法,每一个位置[i,j]都是从该位置的上方[i-1,j]或者左边[i][j-1]移动而来,因此状态转移方程为:result[i][j]=result[i-1][j]+result[i][j-1]。
- 优化算法2的空间复杂度。由2分可知,从起点移动到每个位置的移动次数仅与当前位置的左边位置和上边位置有关,因此result[i]=result[i-1]+result[i]。第一个result[i]代表当前位置,第二个result[i]代表当前位置之上的位置。
三、代码
回溯算法
public class Solution {
int result=0;
public int uniquePaths(int m, int n) {
if(m==0 || n==0)
return 0;
uniquePathsCore(m,n,0,0);
return result;
}
private void uniquePathsCore(int m,int n, int i,int j){
if(i==m-1 && j==n-1){
result++;
return;
}
if(i+1<m){
uniquePathsCore(m,n,i+1,j);
}
if(j+1<n)
uniquePathsCore(m,n,i,j+1);
}
}
动态代理
public class Solution {
public int uniquePaths(int m, int n) {
if(m==0 || n==0)
return 0;
int[][] result=new int[m][n];
for(int j=1;j<n;j++)
result[0][j]=1;
for(int i=0;i<m;i++)
result[i][0]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
result[i][j]=result[i-1][j]+result[i][j-1];
}
}
return result[m-1][n-1];
}
}
动态代理优化
public class Solution {
public int uniquePaths(int m, int n) {
if(m==0 || n==0)
return 0;
int[] result=new int[n];
for(int i=0;i<n;i++)
result[i]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
result[j]=result[j-1]+result[j];
}
}
return result[n-1];
}
}