0%

leetcode每日一题-最小路径和

最小路径和

image1

典型的动态规划题,记$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
}