Dynamic Programming学习笔记 (43) - 下降路径最小和 (力扣# 931)

209 阅读1分钟

本题出自力扣题库第931题。题面大意如下:

给定一个n x n的整数数组matrix,返回通过matrix的下降路径的最小和。

下降路径指的是从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)

示例:

输入: matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13

failing1-grid.jpg

题解:

这是一个一目了然的DP问题, 自上而下的DP表达式为

F(row, col)
  = matrix[row][col], row = 0
  = matrix[row][col] + min (F(row - 1, col - 1), F(row - 1, col), F(row - 1, col  + 1))

这里row和col是matrix的行列坐标,F(row, col)返回的是到达(row, col)位置的最小和。我们使用二维DP数组以及双层循环,从上到下,从左到右依次计算各个DP元素的值。循环完成后,最下面一行中的最小值就是问题的答案。

Java代码如下:

class Solution {
    public int minFallingPathSum(int[][] matrix) {
        int N = matrix.length;

        int[][] dp = new int[N][N];

        for (int j = 0; j < N; j++) {
            dp[0][j] = matrix[0][j];
        }

        for (int i = 1; i < N; i++) {
            for (int j = 0; j < N; j++) {
                int min = dp[i - 1][j];
                if (j > 0) {
                    min = Math.min(min, dp[i - 1][j - 1]);
                }
                if (j < N - 1) {
                    min = Math.min(min, dp[i - 1][j + 1]);
                }
                dp[i][j] = matrix[i][j] + min;
            }
        }

        int result = dp[N - 1][0];
        for (int j = 1; j < N; j++) {
            result = Math.min(result, dp[N - 1][j]);
        }
        return result;
    }
}

以上算法可以做进一步优化以直接使用matrix作为DP数组以减少所需的空间复杂度。