今天刷的题是LeetCode第62题,题目要求是:
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?
这个题其实很简单,我首先想到的是回溯算法,但是超时了,具体地代码如下:
private static int count; public static int solution(int m,int n){ count=0; recursion(m,n,0,0); return count; } public static void recursion(int m,int n,int x,int y){ if (x==m-1&&y==n-1){ count++; return; } if (x<m){ recursion(m,n,x+1,y); } if (y<n){ recursion(m,n,x,y+1); } }
然后句考虑到,点xy只能从x-1y和xy-1两个点到达,那么就可以用动态规划来做。具体地代码如下
public static int dp(int m,int n){ 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; } 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]; } } return dp[m-1][n-1]; }
不过上面的二维数组太占用空间,可以进一步压缩。想象一下,直接把上一行的数搬迁到这一行,那么xy的值就只需要再加上xy-1的值。具体地代码如下:
public static int dp2(int m,int n){ int[] current=new int[n]; Arrays.fill(current,1); for (int i = 1; i <m ; i++) { for (int j = 1; j <n ; j++) { current[j]+=current[j-1]; } } return current[n-1]; }