[LeetCode] Triangle 三角形
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below.
For example, given the following triangle
[
[2],
[3,4],
[6,5,7],
[4,1,8,3]
]
The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
Note:
Bonus point if you are able to do this using only O(n) extra space, where n is the total number of rows in the triangle.
这道题给了我们一个二维数组组成的三角形,让我们寻找一条自上而下的路径,使得路径和最短。那么那道题后还是先考虑下暴力破解,我们可以发现如果要遍历所有的路径的话,那可以是阶乘级的时间复杂度啊,OJ必灭之,趁早断了念想比较好。必须要优化时间复杂度啊,题目中给的例子很容易把人带偏,让人误以为贪婪算法可以解题,因为看题例子中的红色数组,在根数字2的下方选小的数字3,在3的下方选小的数字5,在5的下方选小的数字1,每次只要选下一层相邻的两个数字中较小的一个,似乎就能得到答案了。其实是不对的,贪婪算法可以带到了局部最小,但不能保证每次都带到全局最小,很有可能在其他的分支的底层的数字突然变的超级小,但是贪婪算法已经将其他所有分支剪掉了。所以为了保证我们能得到全局最小,动态规划Dynamic Programming还是不二之选啊。其实这道题和 Dungeon Game 非常的类似,都是用DP来求解的问题。那么其实我们可以不新建dp数组,而是直接复用triangle数组,我们希望一层一层的累加下来,从而使得 triangle[i][j] 是从最顶层到 (i, j) 位置的最小路径和,那么我们如何得到状态转移方程呢?其实也不难,因为每个结点能往下走的只有跟它相邻的两个数字,那么每个位置 (i, j) 也就只能从上层跟它相邻的两个位置过来,也就是 (i-1, j-1) 和 (i-1, j) 这两个位置,那么状态转移方程为:
triangle[i][j] = min(triangle[i - 1][j - 1], triangle[i - 1][j])
我们从第二行开始更新,注意两边的数字直接赋值上一行的边界值,那么最终我们只要在最底层找出值最小的数字,就是全局最小的路径和啦,代码如下:
解法一:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
for (int i = ; i < triangle.size(); ++i) {
for (int j = ; j < triangle[i].size(); ++j) {
if (j == ) {
triangle[i][j] += triangle[i - ][j];
} else if (j == triangle[i].size() - ) {
triangle[i][j] += triangle[i - ][j - ];
} else {
triangle[i][j] += min(triangle[i - ][j - ], triangle[i - ][j]);
}
}
}
return *min_element(triangle.back().begin(), triangle.back().end());
}
};
这种方法可以通过OJ,但是毕竟修改了原始数组triangle,并不是很理想的方法。在网上搜到一种更好的DP方法,这种方法复制了三角形最后一行,作为用来更新的一位数组。然后逐个遍历这个DP数组,对于每个数字,和它之后的元素比较选择较小的再加上面一行相邻位置的元素做为新的元素,然后一层一层的向上扫描,整个过程和冒泡排序的原理差不多,最后最小的元素都冒到前面,第一个元素即为所求。代码如下:
解法二:
class Solution {
public:
int minimumTotal(vector<vector<int>>& triangle) {
vector<int> dp(triangle.back());
for (int i = (int)triangle.size() - ; i >= ; --i) {
for (int j = ; j <= i; ++j) {
dp[j] = min(dp[j], dp[j + ]) + triangle[i][j];
}
}
return dp[];
}
};
下面我们来看一个例子,对于输入数组:
-1
2 3
1 -1 -3
5 3 -1 2
下面我们来看DP数组的变换过程(红色数字为每次dp数组中值改变的位置):
DP:5 3 -1 2
DP: 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
参考资料:
https://leetcode.com/problems/triangle/
https://leetcode.com/problems/triangle/discuss/38730/DP-Solution-for-Triangle
https://leetcode.com/problems/triangle/discuss/38918/C%2B%2B-top-down-and-bottom-up-solutions.
LeetCode All in One 题目讲解汇总(持续更新中...)
[LeetCode] Triangle 三角形的更多相关文章
- LeetCode Triangle 三角形(最短路)
题意:给一个用序列堆成的三角形,第n层的元素个数为n,从顶往下,每个元素可以选择与自己最近的两个下层元素往下走,类似一棵二叉树,求最短路. [], [,4], [6,,7], [4,,8,3] 注意: ...
- [LeetCode 120] - 三角形(Triangle)
问题 给出一个三角形,找出从顶部至底部的最小路径和.每一步你只能移动到下一行的邻接数字. 例如,给出如下三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 从顶部至底部的最 ...
- LeetCode 976. Largest Perimeter Triangle (三角形的最大周长)
题目标签:Array 题目给了我们一个 边长的 array, 让我们找出 最大边长和的三角形,当然前提得是这三条边能组成三角形.如果array 里得边长组成不了三角形,返回0. 最直接的理解就是,找到 ...
- LeetCode 976. 三角形的最大周长(Largest Perimeter Triangle) 33
976. 三角形的最大周长 976. Largest Perimeter Triangle 题目描述 给定由一些正数(代表长度)组成的数组 A,返回由其中三个长度组成的.面积不为零的三角形的最大周长. ...
- LeetCode 120. Triangle三角形最小路径和 (C++)
题目: Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjace ...
- LeetCode 120. 三角形最小路径和(Triangle)
题目描述 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径 ...
- LeetCode 120. Triangle (三角形最小路径和)详解
题目详情 给定一个三角形,找出自顶向下的最小路径和.每一步只能移动到下一行中相邻的结点上. 例如,给定三角形: [ [2], [3,4], [6,5,7], [4,1,8,3] ] 自顶向下的最小路径 ...
- leetcode — triangle
/** * Source : https://oj.leetcode.com/problems/triangle/ * * * Given a triangle, find the minimum p ...
- 120 Triangle 三角形最小路径和
给出一个三角形(数据数组),找出从上往下的最小路径和.每一步只能移动到下一行中的相邻结点上.比如,给你如下三角形:[ [2], [3,4], [6,5,7], [4,1,8,3]] ...
随机推荐
- 使用localResizeIMG3+WebAPI实现手机端图片上传
前言 惯例~惯例~昨天发表的使用OWIN作为WebAPI的宿主..嗯..有很多人问..是不是缺少了什么 - - 好吧,如果你要把OWIN寄宿在其他的地方...代码如下: namespace Conso ...
- .net汉字转字母
目前手上有一个需要实现:将用户输入的姓名转换成汉语拼音. 使用枚举,既麻烦又易出错,发现有一个微软拼音转换工具类ChnCharInfo.dll,在此记录下: 首先需要引入此dll, 链接: http: ...
- web 开发自动化grunt
现在web开发自动化已很流行,如何进行压缩文件,如何进行测试js是否正确,如何进行 检测html文件是否规范等等都可以通过web自动化技术进行实现,只要打一个命令即可. 本文主要是通过grunt进行实 ...
- JavaScript原型链分析
Js之原型链 1.object 与 Object 1.object是类型,表示对象类型 2.Object是函数 2.js成员的访问规则 o.方法( ...
- session的使用方法详解
session的使用方法详解 Session是什么呢?简单来说就是服务器给客户端的一个编号.当一台WWW服务器运行时,可能有若干个用户浏览正在运正在这台服务器上的网站.当每个用户首次与这台WWW服务器 ...
- zip函数-Python 3
zip函数接受任意多个(包括0个和1个)序列作为参数,返回一个tuple列表. zip函数在获取数据后,生成字典(dict)时比较好用. for examples: # Code based on P ...
- java.lang.Class.isAssignableFrom()用法解析
一.概述: 此方法主要用来判断 "参数类" 是否是 "源类" 的子类.接口实现类,或者与 "源类" 相同,在此情况下返回 true; 二.格 ...
- filter 过滤器(监听)
Filter 过滤器 1.简介 Filter也称之为过滤器,它是Servlet技术中最实用的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, ...
- 5分钟创建一个SpringBoot + Themeleaf的HelloWord应用
第一步:用IDE创建一个普通maven工程,我用的eclipse. 第二步:修改pom.xml,加入支持SpringBoot和Themeleaf的依赖,文件内容如下: <?xml version ...
- Lightbox改造——支持滚轮缩放
在做文章类型的web页时,经常会遇到要点开看大图的需求,LightBox2则是在众多产品中比较优秀的一款Jquery插件.配置就不细说了,今天我主要要分享的是:如何在点开大图后,可以通过鼠标滚轮来缩放 ...