2013.12.21 23:32
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Solution1:
Given a 2-d matrix of size m x n, with all elements non-negative, find a down-right path that adds up to a minimal sum. This problem can be solved using dynamic programming.
Recurrence relation is sum[x][y] = min(sum[x - 1][y], sum[x][y - 1]) + a[x][y], where sum[x][y] is the minimum path sum of position (x, y), and a[x][y] is the element at position (x, y).
Time complexity is O(m * n), space complexity is O(m * n).
Accepted code:
1 // 1AC 2 class Solution { 3 public: 4 int minPathSum(vector<vector<int> > &grid) { 5 // IMPORTANT: Please reset any member data you declared, as 6 // the same Solution instance will be reused for each test case. 7 int m, n; 8 9 m = grid.size(); 10 if(m <= 0){ 11 return 0; 12 } 13 14 n = grid[0].size(); 15 if(n <= 0){ 16 return 0; 17 } 18 19 int **arr = new int*[m]; 20 int i, j; 21 22 for(i = 0; i < m; ++i){ 23 arr[i] = new int[n]; 24 } 25 26 arr[0][0] = grid[0][0]; 27 for(i = 1; i < m; ++i){ 28 arr[i][0] = arr[i - 1][0] + grid[i][0]; 29 } 30 for(i = 1; i < n; ++i){ 31 arr[0][i] = arr[0][i - 1] + grid[0][i]; 32 } 33 for(i = 1; i < m; ++i){ 34 for(j = 1; j < n; ++j){ 35 arr[i][j] = mymin(arr[i - 1][j], arr[i][j - 1]) + grid[i][j]; 36 } 37 } 38 39 j = arr[m - 1][n - 1]; 40 41 for(i = 0; i < m; ++i){ 42 delete[] arr[i]; 43 } 44 delete[] arr; 45 return j; 46 } 47 private: 48 const int &mymin(const int &x, const int &y) { 49 return (x < y ? x : y); 50 } 51 };
Solution2:
Apparently, this problem still has some space for optimization. The space complexity can be reduced to linear. Since the recurrence relation only involves sum[x - 1][y] and sum[x][y - 1], the calculation of sum[x][y] only depends on the (x - 1)th and xth row (or column, if you like). Therefore, only two rows of extra space are needed for dynamic programming.
Time complexity is O(m * n), space complexity is O(n).
Accepted code:
1 // 1WA, 1AC, could've been perfect 2 class Solution { 3 public: 4 int minPathSum(vector<vector<int> > &grid) { 5 // IMPORTANT: Please reset any member data you declared, as 6 // the same Solution instance will be reused for each test case. 7 int m, n; 8 9 m = grid.size(); 10 if(m <= 0){ 11 return 0; 12 } 13 14 n = grid[0].size(); 15 if(n <= 0){ 16 return 0; 17 } 18 19 int **arr = new int*[2]; 20 int i, j; 21 int flag; 22 23 for(i = 0; i < 2; ++i){ 24 arr[i] = new int[n]; 25 } 26 27 flag = 0; 28 arr[flag][0] = grid[0][0]; 29 for(i = 1; i < n; ++i){ 30 arr[flag][i] = arr[flag][i - 1] + grid[0][i]; 31 } 32 for(i = 1; i < m; ++i){ 33 flag = !flag; 34 // 1WA here, forgot to add grid[i][0] 35 arr[flag][0] = arr[!flag][0] + grid[i][0]; 36 for(j = 1; j < n; ++j){ 37 arr[flag][j] = mymin(arr[!flag][j], arr[flag][j - 1]) + grid[i][j]; 38 } 39 } 40 41 j = arr[flag][n - 1]; 42 43 for(i = 0; i < 2; ++i){ 44 delete[] arr[i]; 45 } 46 delete[] arr; 47 return j; 48 } 49 private: 50 const int &mymin(const int &x, const int &y) { 51 return (x < y ? x : y); 52 } 53 };