Leetcode 931. 下降路径最小和 | 刷题打卡

276 阅读2分钟

题目描述

给你一个 n x n 的 方形 整数数组 matrix ,请你找出并返回通过 matrix 的下降路径的最小和 。

下降路径 可以从第一行中的任何元素开始,并从每一行中选择一个元素。在下一行选择的元素和当前行所选元素最多相隔一列(即位于正下方或者沿对角线向左或者向右的第一个元素)。具体来说,位置 (row, col) 的下一个元素应当是 (row + 1, col - 1)、(row + 1, col) 或者 (row + 1, col + 1) 。

输入:matrix = [[2,1,3],[6,5,4],[7,8,9]]
输出:13
解释:下面是两条和最小的下降路径,用加粗标注:
[[2,1,3],      [[2,1,3],
 [6,5,4],       [6,5,4],
 [7,8,9]]       [7,8,9]]

他们的路径是 1 -> 4 -> 8 或者 1 -> 5 -> 7

思路分析

我们通过题目可以知道我们求的是最小和,又是熟悉的字,通常带有这种字眼的题目,都是使用动态规划进行解题。

那么按照动态规划的解题步骤,我们需要先找出状态,这里的状态很明显就是最小和。然后我们要做出选择,选择就是二维数组里面的每一个数字,最后我们要初始化,因为题目中提到下降路径可以从第一行中的任何元素开始,所以我们的 dp 数组的初始化就是第一行元素,然后我们只要每次都从下一行中找出最小的数字进行相加,就可以得到我们的结果。

举个栗子:

image.png

我们从 2 开始出发,每一次都找到下一行中的最小的数组,那么就可以找到从 2 出发能够得到的最小和。然后我们依次从 1 和 3 出发得到各自的最小和,最后比较所有的路径的最小和,最小的那个便是答案。

AC 代码

public int minFallingPathSum(int[][] matrix) {
    int[] row1 = matrix[0];
    int[][] dp = new int[matrix.length][matrix[0].length];
    // 初始化
    for(int i = 0; i < matrix[0].length; i++){
        dp[0][i] = matrix[0][i];
    }

    // 从第一行开始得到每一条路径的最小和
    for(int i = 1; i < matrix.length; i++){
        for(int j = 0; j < matrix[0].length; j++){
            if(j == 0) dp[i][j] = Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[i - 1][j + 1]);
            else if(j == matrix[0].length - 1) dp[i][j] = Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[i - 1][j - 1]);
            else dp[i][j] = Math.min(Math.min(matrix[i][j] + dp[i - 1][j], matrix[i][j] + dp[ i - 1][j - 1]), matrix[i][j] + dp[i - 1][j + 1]);
        }
    }

    int res = Integer.MAX_VALUE;
    
    // 从所有最小和中得到最小的那个
    for(int i = 0; i < dp[0].length; i++){
        if(res > dp[dp[0].length - 1][i]){
            res = dp[dp[0].length - 1][i];
        }
    }
    return res;
}

总结

这就是一道基础的动态规划题目,只要按照动态规划的解题步骤即可得出答案。

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情