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 }

这道题真是相当经典。

 

 

你可能感兴趣的:(LeetCode)