Leetcode 1289.下降路径最小和II

目录

1289. 下降路径最小和 II - 力扣(LeetCode)

 思路解析


1289. 下降路径最小和 II - 力扣(LeetCode)

 

 

 思路解析

首先关注到这道题是一个 “路径最优化” 的题目。因此,我们通常可以使用 DAGDP(有向图动态规划) 解决。

所以,我们的解决算法关注到 “动态规划”。接下来我们分析最优结构的特征信息。因为我们需要返回最小路径和,那么我们的最优子结构应该存放 最小路径和。接下来,因为我们的起点是不固定的,而终点是固定可知的。所以我们不妨记 dp(i, j) 表示以第 i 行第 j 列为终点的最小和

状态转移方程为:

dp[i][j] = min\left \{ dp[i-1][k] + arr[i][j] \right \},其中 k\neq j

至此我们发现,我们需要一层循环遍历 j,一层循环遍历 k,还需要一次循环遍历 i。至此我们发现算法的时间复杂度在O(n^{3}),当然面对这一道题目毛估估是可以过关的。因为 n 最大也就200。

这一段代码符合常理,也好编写。所以,我们不做展示。

接下来,我们经行优化。在遍历寻找的最小位置的时候,我们发现:如果第 i-1 行的最小值位置为 pos,那么除了 dp[i][pos] 外,其他列的最小值都应该由该位置转移而来。那么dp[i][pos]就应该从第 i-1 行第2小的位置转移而来

基于此,我们可以撤销遍历k的循环,从而使用 first_sum,first_pos,second_sum来代替。注意第2小的位置我们无需关心,因为一定不会跟第1小的位置相同。

因为最后的答案就是第 i 行的 first_sum。所以我们在这里还可以撤销dp数组的额外空间。

AC代码

class Solution {
public:
    int minFallingPathSum(vector<vector<int>>& grid) {
        int n = grid.size();
        
        int first_sum = 0, first_pos = -1, second_sum = 0;//初始化不对第 0 行的值有影响即可
        for (int i = 0; i < n; ++i) {
            int cur_fs = INT_MAX, cur_fp = -1, cur_ss = INT_MAX;//寻找当前的前两个小值
            for (int j = 0; j < n; ++j) {
                int cur_sum = (j == first_pos? second_sum: first_sum) + grid[i][j];

                if (cur_sum < cur_fs) {
                    cur_ss = cur_fs;
                    cur_fs = cur_sum;
                    cur_fp = j;
                }
                else if (cur_sum < cur_ss) {
                    cur_ss = cur_sum;
                }
            }

            //更新first_sum, first_pos, second_sum值
            first_sum = cur_fs;
            first_pos = cur_fp;
            second_sum = cur_ss;
        }

        return first_sum;//返回第 n - 1行的最小值
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值