题目描述
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出两块最重的石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:如果 x==y,那么两块石头都会被完全粉碎;如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。最后,最多只会剩下一块石头。返回此石头的重量。如果没有石头剩下,就返回 0。
提示:
1 <= stones.length <= 30
1 <= stones[i] <= 1000
解法1:优先队列
队列按照降序的顺序,即最大的两个元素为队首的两个元素。取队首元素为y,队首元素出队;再去队首元素为x,队首元素出队。如果y>x,将y-x入队;否则,不做处理。退出循环时,如果队列为空,返回0;否则,返回最后剩下的元素。
//priority_queue
class Solution {
public:
int lastStoneWeight(vector<int>& stones) {
priority_queue<int> q (stones.begin(), stones.end());
while(q.size()>1)
{
int y = q.top();
q.pop();
int x = q.top();
q.pop();
if(y>x) q.push(y-x);
}
return q.empty() ? 0 : q.top();
}
};
解法2:普通数组排序解法
将数组用sort函数按升序排序,如果数组只有一个元素,则直接返回该元素。否则,数组最后一个元素变为数组最后一个元素减去数组倒数第二个元素的差,数组倒数第二个元素变为0,重新排序。
class Solution {
public:
int lastStoneWeight(vector<int>& stones)
{
int len=stones.size();
if(len==1) return stones[0];
sort(stones.begin(),stones.end());
while(stones[len-2]!=0){
stones[len-1]=stones[len-1]-stones[len-2];
stones[len-2]=0;
sort(stones.begin(),stones.end());
}
return stones[len-1];
}
};
解法3:multiset用法
c++语言中,multiset是库中一个非常有用的类型,它可以看成一个序列,插入一个数,删除一个数都能够在O(logn)的时间内完成,而且他能时刻保证序列中的数是有序的,而且序列中可以存在重复的数。
函数逻辑类似于普通数组排序解法。
// multiset 方法
class Solution {
public:
int lastStoneWeight(vector<int>& stones) {
multiset<int>s(stones.begin(), stones.end());
while(s.size()>1)
{
int y = *prev(s.end()); // 获取最后一个位置的值
s.erase(prev(s.end())); // 删除最后一个位置元素
int x = *prev(s.end());
s.erase(prev(s.end()));
if(y-x>0)
s.insert(y-x);
}
return s.empty() ? 0: *s.begin();
}
};