LeetCode | Unique Paths【摘】

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?

最简单的回溯:

1 int backtrack(int r, int c, int m, int n) {
2   if (r == m && c == n)
3     return 1;
4   if (r > m || c > n)
5     return 0;
6  
7   return backtrack(r+1, c, m, n) + backtrack(r, c+1, m, n);
8 }

用一个表记录状态,优化:

 1 const int M_MAX = 100;
 2 const int N_MAX = 100;
 3  
 4 int backtrack(int r, int c, int m, int n, int mat[][N_MAX+2]) {
 5   if (r == m && c == n)
 6     return 1;
 7   if (r > m || c > n)
 8     return 0;
 9  
10   if (mat[r+1][c] == -1)
11     mat[r+1][c] = backtrack(r+1, c, m, n, mat);
12   if (mat[r][c+1] == -1)
13     mat[r][c+1] = backtrack(r, c+1, m, n, mat);
14  
15   return mat[r+1][c] + mat[r][c+1];
16 }
17  
18 int bt(int m, int n) {
19   int mat[M_MAX+2][N_MAX+2];
20   for (int i = 0; i < M_MAX+2; i++) {
21     for (int j = 0; j < N_MAX+2; j++) {
22       mat[i][j] = -1;
23     }
24   }
25   return backtrack(1, 1, m, n, mat);
26 }

动态规划,从最靠近终点的地方(子问题)开始算:

 1 const int M_MAX = 100;
 2 const int N_MAX = 100;
 3  
 4 int dp(int m, int n) {
 5   int mat[M_MAX+2][N_MAX+2] = {0};
 6   mat[m][n+1] = 1;
 7  
 8   for (int r = m; r >= 1; r--)
 9     for (int c = n; c >= 1; c--)
10       mat[r][c] = mat[r+1][c] + mat[r][c+1];
11  
12   return mat[1][1];
13 }

这里的空间可以进一步优化,因为最底行计算完之后可以直接用来计算上一行。

 1 class Solution {
 2 public:
 3     int uniquePaths(int m, int n) {
 4         vector<int> map(m+1, 0);
 5         map[1]=1;
 6         for(int i=0; i<n; i++){
 7             for(int j=1; j<=m; j++)
 8                 map[j] = map[j-1]+map[j];
 9         }
10         return map[m];
11     }
12 }

另外,这道题其实也是一个组合数学的题,结果就是C(m + n - 2, n - 1)。这里要注意计算是overflow。

 1 int gcd(int a, int b) {
 2     while(b) {
 3         int c = a%b;
 4         a = b;
 5         b = c;
 6     }
 7     return a;
 8 }
 9 
10 int C(int m, int n) {
11     if(m - n < n) {
12         n = m - n;
13     }
14     int result = 1;
15     for(int i = 1; i <= n; i++) {
16         int mult = m;
17         int divi = i;
18         int g = gcd(mult,divi);
19         mult /= g;
20         divi /= g;
21         result /= divi;
22         result *= mult;
23         m--;
24     }
25     return result;
26 }

这道题真是相当经典。

 

 

posted @ 2014-04-08 19:10  linyx  阅读(139)  评论(0编辑  收藏  举报