leetcode 62. Unique Paths

来源:互联网 发布:上海电气待遇 知乎 编辑:程序博客网 时间:2024/05/29 12:52

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.


这道题可以用递归with memory来做。某个格子到终点的路径数 = 它右边的格子到终点的路径数 + 它下面的格子到终点的路径数。
public int uniquePaths(int m, int n) {int[][] directions=new int[][]{{0,1},{1,0}};//{0,1}是右移,{1,0}是下移Integer[][] memo=new Integer[m][n];memo[m-1][n-1]=1;//初始位置在(1,1),要走到(m,n)return move(1, 1, m, n, directions, memo);}public int move(int curX,int curY,int m,int n,int[][] directions,Integer[][] memo){if(curX>m||curY>n){return 0;}if(memo[curX-1][curY-1]!=null){return memo[curX-1][curY-1];}int rightCount=move(curX+directions[0][0], curY+directions[0][1], m, n,directions, memo);int downCount=move(curX+directions[1][0], curY+directions[1][1], m, n,directions, memo);memo[curX-1][curY-1]=rightCount+downCount;return memo[curX-1][curY-1];}
既然可以用递归+memory来做,那么就可以用DP来做了。

假设 DP[i][j] 是 ( i , j ) 坐标的格子到终点的路径数。如下图所示。


可以看到最下面一行的DP值都是1,而 上面行的格子值 可以从右到左 根据其右边和下面的格子值相加 算出来。即DP[i][j] = DP[i + 1][j] + DP[i][j + 1].

public int DP(int m,int n){int[][] dp=new int[m][n];for(int y=0;y<n;y++){dp[m-1][y]=1;//最下面一行全是1}for(int x=m-2;x>=0;x--){//从下面倒数第二层,一层层往上填充for(int y=n-1;y>=0;y--){int count=0;if(y==n-1){//最右边缘count+=dp[x+1][y];}else{count+=(dp[x+1][y]+dp[x][y+1]);}dp[x][y]=count;}}return dp[0][0];}

大神还有另外一种神奇的解法:运用排列组合的思想。

从 (1, 1) 移动到 ( m , n ),我们需要有 n + m - 2 次移动: m - 1 次下移和 n - 1 次右移。
移动序列可以表示为 D(go down)和 R(go right)。如这是3*7表格的一个移动序列:D R R R D R R R。
那么,只要这个序列不同,走的路径也不同。有多少种不同的序列,就是排列组合问题了:
从 (m + n - 2) 个位置中选择 (n - 1)  个位置来放入 R。剩下的 (m - 1) 位置全是 D。即我们需要的结果是C(n-1/m+n-2)

class Solution {    public:        int uniquePaths(int m, int n) {            int N = n + m - 2;// how much steps we need to do            int k = m - 1; // number of steps that need to go down            double res = 1;            // here we calculate the Combination(N, k)             // C = ( n * (n - 1) * (n - 2) * ... * (n - k + 1) / k!            // C = ( (n - k + 1) * (n - k + 2) * ... * n ) / k!            // C = (n-k+1)/1 * (n-k+2)/2 * (n-k+3)/3 * ... * (n-k+k)/k            for (int i = 1; i <= k; i++)                res = res * (N - k + i) / i;            return (int)res;        }};


原创粉丝点击