zoukankan      html  css  js  c++  java
  • LeetCode(120):三角形最小路径和

    Medium!

    题目描述:

    给定一个三角形,找出自顶向下的最小路径和。每一步只能移动到下一行中相邻的结点上。

    例如,给定三角形:

    [
         [2],
        [3,4],
       [6,5,7],
      [4,1,8,3]
    ]
    

    自顶向下的最小路径和为 11(即,2 + 3 + 5 + 1 = 11)。

    说明:

    如果你可以只使用 O(n) 的额外空间(n 为三角形的总行数)来解决这个问题,那么你的算法会很加分。

    解题思路:

    这道题和Dungeon Game 地牢游戏非常的类似,都是用动态规划Dynamic Programming来求解的问题。而且递推式也比较容易看出来,最先想到的方法是:

    从第二行开始,triangle[i][j] = min(triangle[i - 1][j - 1], triangle[i - 1][j]), 然后两边的数字直接赋值上一行的边界值,由于限制了空间复杂度,所以干脆直接就更新triangle数组。

    C++解法一:

     1 class Solution {
     2 public:
     3     int minimumTotal(vector<vector<int> > &triangle) {
     4         int n = triangle.size();
     5         for (int i = 1; i < n; ++i) {
     6             for (int j = 0; j < triangle[i].size(); ++j) {
     7                 if (j == 0) triangle[i][j] += triangle[i - 1][j];
     8                 else if (j == triangle[i].size() - 1) triangle[i][j] += triangle[i - 1][j - 1];
     9                 else {
    10                     triangle[i][j] += min(triangle[i - 1][j - 1], triangle[i - 1][j]);
    11                 }
    12             }
    13         }
    14         int res = triangle[n - 1][0];
    15         for (int i = 0; i < triangle[n - 1].size(); ++i) {
    16             res = min(res, triangle[n - 1][i]);
    17         }
    18         return res;
    19     }
    20 };

    这种方法可以通过OJ,但是毕竟修改了原始数组triangle,并不是很理想的方法。在网上搜到一种更好的DP方法,这种方法复制了三角形最后一行,作为用来更新的一维数组。然后逐个遍历这个DP数组,对于每个数字,和它之后的元素比较选择较小的再加上上面一行相邻位置的元素做为新的元素,然后一层一层的向上扫描,整个过程和冒泡排序的原理差不多,最后最小的元素都冒到前面,第一个元素即为所求。

    C++解法二:

     1 class Solution {
     2 public:
     3     int minimumTotal(vector<vector<int> > &triangle) {
     4         int n = triangle.size();
     5         vector<int> dp(triangle.back());
     6         for (int i = n - 2; i >= 0; --i) {
     7             for (int j = 0; j <= i; ++j) {
     8                 dp[j] = min(dp[j], dp[j + 1]) + triangle[i][j];
     9             }
    10         }
    11         return dp[0];
    12     }
    13 };

    下面我们来看一个例子,对于输入数组:

         -1

        2   3

      1  -1  -3

    5   3   -1   2

    下面我们来看DP数组的变换过程。

    DP:5  3  -1  2

    DP:4  3  -1  2

    DP:4  -2  -1  2

    DP:4  -2  -4  2

    DP: -2  -4  2

    DP:0  -1  -4  2

    DP:-2  -1  -4  2

  • 相关阅读:
    《区块链100问》第33集:在交易平台投资区块链资产
    Python学习(三)数组属性方法总结
    Python学习(二)Numpy学习
    数学之美 第2章 自然语言处理:从规则到统计
    数学之美 第1章 文字和语言 vs 数字和信息
    Python学习(一)基础知识
    Python使用技巧(不定期更新)
    玩转Git三剑客——04. 创建第一个仓库并配置local用户信息、05. 通过几次commit来认识工作区和暂存区
    玩转Git三剑客——02. 安装Git、03. 使用Git之前需要做的最小配置
    玩转Git三剑客——01. 课程综述
  • 原文地址:https://www.cnblogs.com/ariel-dreamland/p/9165946.html
Copyright © 2011-2022 走看看