使用priority_queue解决最大堆问题。
来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/last-stone-weight 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
1046. 最后一块石头的重量
题目描述
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
- 如果
x == y,那么两块石头都会被完全粉碎; - 如果
x != y,那么重量为x的石头将会完全粉碎,而重量为y的石头新重量为y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回0。
示例:
1 | 输入:[2,7,4,1,8,1] |
题目解析
这道题读完题后感觉并不是太难,只要对这堆石头,每次找出最大的两块然后敲碎,全部丢掉或者留下一块小石头继续就行了。可是我却很难想到一个高效的方法来解决这个问题。如果要使用一个有效的数据结构,那么这个结构要能保存一个按大小排列的数组,并在每次取出最大的两个数后,将可能剩下的一个数插入数组,并保持数组的有序性。如果每次都使用一次排序的话未免太复杂了些,如果使用之前刚刚学过的单调栈,又不能在敲碎两块石头后有效的处理剩下的一块石头。队列和栈看起来也不好处理这个问题。无奈之下只好再次求助答案,结果看到了“最大堆”这个说法,恍然大悟!
其实堆很久以前数据结构就学过,大致记得是一个以二叉树形式存储数据,使所有数据满足“父节点的数值大于子节点数值”的一个数据结构。在学排序的时候还学过堆排序,应该就是先构建一个堆,然后就很好排序了。不过说实话我早就忘记了怎么实现这个数据结构,看来之后还要好好复习一下。。。。。。不过我也不记得STL里面专门有heap这种类型的数据结构,所以虽然知道了大概的方法,但还是写不出来😂
又瞟了一眼别人答案的代码,一眼看到了一个奇怪的东西priority_queue,我寻思队列怎么跟堆也扯不上关系,为啥这个优先队列就行呢?结果一看优先队列的使用方式才发现,这个“优先”正是通过堆来实现的!
优先队列priority_queue通过与普通queue不同的地方就在于,队列中的数据优先级可以定义,并自动根据优先级排队,按照优先级顺序出队。其余入队、出队的方式就与queue一样了。底层由一个堆实现,默认是按照大根堆来实现的,也就是说,大的元素在最顶端。于是在这道题中,就可以将所有石块加入这个优先队列,这样他们就会自动按照从大到小的顺序排序,并在每次更新,加入新的石块时仍然保持排序不变。
按照概念自己瞎写了个代码,最终正确通过了,看来以后还是在刷题的同时要好好学习和复习数据结构方面的知识。
代码
1 | class Solution { |