题目
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块 最重的 石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。
循环排序
这个解法就是循环排序,特别消耗性能
int lastStoneWeight(vector<int>& stones) {
if (stones.size() == 1) {
return stones[0];
}
for (int i = 0; i < stones.size(); i++) {
sort(stones.rbegin(), stones.rend());
stones[0] -= stones[1];
stones[1] = 0;
}
return stones[0];
}
最大堆
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> q;
for (int i = 0; i < stones.size(); i++) {
q.push(stones[i]);
}
while (q.size() > 1) {
int a = q.top();
q.pop();
int b = q.top();
q.pop();
if (a > b) {
q.push(a - b);
}
}
return q.empty() ? 0 : q.top();
}
可以看到上边两种解法的时间复杂度相差不是一点半点
最大堆相关知识
最大堆其实就是优先队列,需要包含头文件#include
它和队列不同的地方就在于我们可以自定义其中数据的优先级,让优先级高的排在前面,优先出队
优先队列具有和队列相同的所有特性
如果大家对于队列不是很熟悉 我给大家一篇我之前写的c#的栈和队列的博客给大家参考
c#栈和队列介绍地址
下面就是声明的时候的方法
//对于基础类型 默认是大顶堆
priority_queue<int> a;
//等同于 priority_queue<int, vector<int>, less<int> > a;
//这里一定要有空格,不然成了右移运算符↓
priority_queue<int, vector<int>, greater<int> > c; //这样就是小顶堆
具体优先队列的使用我就不举例介绍了
希望我所写的对大家有帮助