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 }
这道题真是相当经典。