作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/last-stone-weight/

题目描述

We have a collection of rocks, each rock has a positive integer weight.

Each turn, we choose the two heaviest rocks and smash them together. Suppose the stones have weights x and y with x <= y. The result of this smash is:

- If x == y, both stones are totally destroyed;
- If x != y, the stone of weight x is totally destroyed, and the stone of weight y has new weight y-x.

At the end, there is at most 1 stone left. Return the weight of this stone (or 0 if there are no stones left.)

Example 1:

Input: [2,7,4,1,8,1]
Output: 1
Explanation:
We combine 7 and 8 to get 1 so the array converts to [2,4,1,1,1] then,
we combine 2 and 4 to get 2 so the array converts to [2,1,1,1] then,
we combine 2 and 1 to get 1 so the array converts to [1,1,1] then,
we combine 1 and 1 to get 0 so the array converts to [1] then that's the value of last stone.

Note:

  1. 1 <= stones.length <= 30
  2. 1 <= stones[i] <= 1000

题目大意

每次拿出两个最大的石头进行抵消。如果两个石头的重量一样,那么都粉碎;否则把大的石头粉碎掉和小的石头同样的重量,然后继续放到石头堆里。最后最多只会剩下一个石头,返回这个石头的重量或者0.

解题方法

大根堆

这个题还是挺经典的,不久前微软面试的时候问过类似的题目。

这个题就是我们在数据结构与算法中都学过的哈弗曼树的改变。哈弗曼树是指每次选择最小的两个元素合并成一个更大的元素,然后和剩下的一些元素继续重复这个操作。而这个题反其道而行之,每次选择最大的两个元素合并成一个较小的元素,然后和剩下的元素重复这个操作。

实现哈弗曼树最简单的方式就是使用堆。显然这个题使用大根堆。在python中的堆默认是小根堆,为了实现大根堆,一个方式是把所有的数字进行取反操作,最后的结果再取反即可。C++的堆默认是大根堆,那么我们就直接使用。

我觉得技术上的难点只有要进行多次的判断。一定要注意在进行pop的时候是否还有元素,特别是这个题要进行两次连续的pop。另外一个注意的点是如果两个石头抵消了,那么结果0就不一样放入原来的数组中了。最后一个注意的点事最后可能全部都抵消了,所以如果结果为空则返回0。

时间复杂度是O(NlogN)。

Python代码如下:

class Solution(object):
def lastStoneWeight(self, stones):
"""
:type stones: List[int]
:rtype: int
"""
stones = map(lambda x : -x, stones)
heapq.heapify(stones)
while len(stones) > 1:
x = heapq.heappop(stones)
if stones:
y = heapq.heappop(stones)
if x != y:
heapq.heappush(stones, -abs(x - y))
return 0 if not stones else -stones[0]

C++代码如下:

class Solution {
public:
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> q;
for (int s : stones)
q.push(s);
while (q.size() >= 2) {
int a = q.top(); q.pop();
if (!q.empty()) {
int b = q.top(); q.pop();
if (a != b) {
q.push(abs(a - b));
}
}
}
return q.empty() ? 0 : q.top();
}
};

日期

2019 年 6 月 8 日 —— 刷题尽量不要停

【LeetCode】1046. Last Stone Weight 解题报告(Python & C++)的更多相关文章

  1. LeetCode 1046. Last Stone Weight

    原题链接在这里:https://leetcode.com/problems/last-stone-weight/ 题目: We have a collection of rocks, each roc ...

  2. leetcode 57 Insert Interval & leetcode 1046 Last Stone Weight & leetcode 1047 Remove All Adjacent Duplicates in String & leetcode 56 Merge Interval

    lc57 Insert Interval 仔细分析题目,发现我们只需要处理那些与插入interval重叠的interval即可,换句话说,那些end早于插入start以及start晚于插入end的in ...

  3. 【LeetCode】877. Stone Game 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 数学 双函数 单函数 + 记忆化递归 动态规划 日期 ...

  4. 【LeetCode】62. Unique Paths 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...

  5. LeetCode 1046. 最后一块石头的重量(1046. Last Stone Weight) 50

    1046. 最后一块石头的重量 1046. Last Stone Weight 题目描述 每日一算法2019/6/22Day 50LeetCode1046. Last Stone Weight Jav ...

  6. 【LeetCode】376. Wiggle Subsequence 解题报告(Python)

    [LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...

  7. 【LeetCode】649. Dota2 Senate 解题报告(Python)

    [LeetCode]649. Dota2 Senate 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地 ...

  8. 【LeetCode】911. Online Election 解题报告(Python)

    [LeetCode]911. Online Election 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ ...

  9. 【LeetCode】886. Possible Bipartition 解题报告(Python)

    [LeetCode]886. Possible Bipartition 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu ...

随机推荐

  1. [R] venn.diagram保存pdf格式文件?

    vennDiagram包中的主函数绘图时,好像不直接支持PDF格式文件: dat = list(a = group_out[[1]][,1],b = group_out[[2]][,1]) names ...

  2. markdown语法之如何使用LaTeX语法编写数学公式

    CSDN-markdown语法之如何使用LaTeX语法编写数学公式 目录 目录 正文 标记公式 行内公式 块级公式 上标和下标 分数表示 各种括号 根号表示 省略号 矢量表示 间隔空间 希腊字母 特殊 ...

  3. MYSQL(3)

    加载C盘下的目录 全表查询 查询部分字段 查询总数 条件过滤 and or 包含 范围检查 between and 否定结果not 匹配任意字符    like 以什么开始^   rlike 以什么结 ...

  4. javaSE高级篇2 — 流技术 — 更新完毕

    1.先认识一个类----File类 前言:IO相关的一些常识 I / O----输入输出 I     输入     input 0    输出     output I / o 按数据的流动方向来分- ...

  5. A Child's History of England.24

    Besides all these troubles, William the Conqueror was troubled by quarrels among his sons. He had th ...

  6. A Child's History of England.37

    Many other noblemen repeating and supporting this when it was once uttered, Stephen and young Planta ...

  7. day34 前端基础之JavaScript

    day34 前端基础之JavaScript ECMAScript 6 尽管 ECMAScript 是一个重要的标准,但它并不是 JavaScript 唯一的部分,当然,也不是唯一被标准化的部分.实际上 ...

  8. C++ 类型转换(C风格的强制转换):

    转https://www.cnblogs.com/Allen-rg/p/6999360.html C++ 类型转换(C风格的强制转换): 在C++基本的数据类型中,可以分为四类:整型,浮点型,字符型, ...

  9. ython学习笔记(接口自动化框架 V2.0)

    这个是根据上次框架版本进行的优化 用python获取excel文件中测试用例数据 通过requets测试接口.并使用正则表达式验证响应信息内容 生成xml文件测试报告 版本更新内容: 1. 整理了Cr ...

  10. SpringMVC responseBody注解分析

    @responsebody表示该方法的返回结果直接写入HTTP response body中一般在异步获取数据时使用,在使用@RequestMapping后,返回值通常解析为跳转路径,加上@respo ...