最小路径和

典型的动态规划题,记$dp[i][j]$为$(i,j)$处的最小路径和,因为只能向下或者向右走,状态转移方程为:
$$
dp[i][j] = min(dp[i-1][j],dp[i][j-1])+grid[i][j]
$$
最后结果就是终点处的值$dp[m-1][n-1]$。
1 | class Solution { | 
2 |     public int minPathSum(int[][] grid) { | 
3 |         int m = grid.length; | 
4 |         int n = grid[0].length; | 
5 |         int[][] dp = new int[m][n]; | 
6 |         dp[0][0] = grid[0][0]; | 
7 |         for(int i=1; i<m; i++){ | 
8 |             dp[i][0] = dp[i-1][0] + grid[i][0]; | 
9 |         } | 
10 |         for(int j=1; j<n; j++){ | 
11 |             dp[0][j] = dp[0][j-1] + grid[0][j]; | 
12 |         } | 
13 |         for(int i=1; i<m; i++){ | 
14 |             for(int j=1; j<n; j++){ | 
15 |                 dp[i][j] = Math.min(dp[i-1][j],dp[i][j-1])+grid[i][j]; | 
16 |             } | 
17 |         } | 
18 |         return dp[m-1][n-1]; | 
19 |     } | 
20 | } | 
复杂度分析:
- 时间复杂度:$O(mn)$。
 - 空间复杂度:$O(mn)$。
 
可以使用滚动数组优化空间复杂度至$O(n)$。
1 | class Solution { | 
2 |     public int minPathSum(int[][] grid) { | 
3 |         int m = grid.length; | 
4 |         int n = grid[0].length; | 
5 |         int[] dp = new int[n]; | 
6 |         dp[0] = grid[0][0]; | 
7 |         for(int i=1; i<n; i++){ | 
8 |             dp[i] = dp[i-1] + grid[0][i]; | 
9 |         } | 
10 |         for(int i=1; i<m; i++){ | 
11 |             for(int j=0; j<n; j++){ | 
12 |                 if(j == 0){ | 
13 |                     dp[0] = dp[0] + grid[i][0]; | 
14 |                     continue; | 
15 |                 } | 
16 |                 dp[j] = Math.min(dp[j],dp[j-1])+grid[i][j]; | 
17 |             } | 
18 |         } | 
19 |         return dp[n-1]; | 
20 |     } | 
21 | } |