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?
Above is a 3 x 7 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
这道题就是说从start走到finish有多少种走法,只能向右或者向下走。
刚开始发现超级简单= =。然后发现天真了,这样超时了。
public class Solution { public int uniquePaths(int m, int n) { if( m<n) return uniquePaths(n,m); if( n == 1) return 1; else return uniquePaths(m,n-1)+uniquePaths(m-1,n); } }
然后进行思考,其实是有规律的,就是在n、m均大于1的情况下,其实答案就是C(num1,num2),但是这样的话,在数据比较大的时候会溢出,所以答案也不对。
public class Solution { public int uniquePaths(int m, int n) { if( m<n) return uniquePaths(n,m); if( n == 1) return 1; int num1 = m+n-2,num2 = n-1; int result = 1; for( int i = 0;i<num2;i++) result*=(num1-i); for( int i = 0;i<num2;i++) result/=(num2-i); return result; } }
利用DP,可以顺利求出结果
在m>n 并且 n >2 的情况下,
uniquePaths(m,n) = uniquePaths(m-1,n) + uniquePaths(m,n-1),
且 uniquePaths(m,n) = uniquePaths(n,m)
所以可以得到一个二维数组,从而得出答案。
public class Solution { public int uniquePaths(int m, int n) { if( m < n) return uniquePaths(n,m); if( n == 1) return 1; if( n == 2) return m; int result[][] = new int[m][m]; result[0][0] = 1; for( int i = 1;i < m ;i++){ result[i][0] = 1; for( int j = 1;j<i;j++){ result[i][j] = result[i-1][j]+result[i][j-1]; } result[i][i] = result[i][i-1]*2; } return result[m-1][n-1]; } }
然后可以继续优化,就是单数组,相当于每次更新之前result数组的每一行。
public class Solution { public int uniquePaths(int m, int n) { if( m < n) return uniquePaths(n,m); if( n == 1) return 1; if( n == 2) return m; int result[] = new int[m]; for( int i = 0;i<m;i++) result[i] = 1; for( int i = 1;i<n;i++) for( int j = 1;j<m;j++) result[j] +=result[j-1]; return result[m-1]; } }