运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:名次第 1 的运动员获金牌 "Gold Medal" 。 名次第 2 的运动员获银牌 "Silver Medal" 。 名次第 3 的运动员获铜牌 "Bronze Medal" 。 从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。 使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
vector<string> ans(n);
priority_queue<pair<int,int>>que;
for( int i = 0;i < n;i++ ) que.push( {score[i],i} );
int k = 3;//前三名
while( k && !que.empty() ){
int index = que.top().second;
que.pop();
switch (k){
case 3 : ans[index] = "Gold Medal";break;
case 2 : ans[index] = "Silver Medal";break;
case 1 : ans[index] = "Bronze Medal";break;
}
k--;
}
k = 4; //依次排序
while( !que.empty() ){
int index = que.top().second;
ans[index] = to_string(k);
++k;
que.pop();
}
return ans;
}
};
703 数据流中的第K大元素
堆 priority_queue<Type, Container, Functional> Type 为数据类型, Container 为保存数据的容器,Functional 为元素比较方式。 如果不写后两个参数,那么容器默认用的是 vector,比较方式默认用 operator<,也就是优先队列是大顶堆,队头元素最大,本题为小顶堆。
class KthLargest {
int K;
priority_queue<int, vector<int>, greater<int>> pq;
public:
KthLargest(int k, vector<int>& nums) {
for (int n : nums) {
pq.push(n);
if (pq.size() > k) pq.pop();
}
K = k;
}
int add(int val) {
pq.push(val);
if (pq.size() > K) pq.pop();
return pq.top();
}
};
23. 合并 K 个升序链表
用优先队列 priority_queue 保存 ListNode* 指针,并按照链表节点的值 val 进行排序。 需要给 priority_queue 提供自定义的排序比较函数子
struct MyCmp { // return true if right < left, to make priority_queue a min heap
bool operator()(ListNode* lhs, ListNode* rhs) const {
if (lhs != nullptr && rhs != nullptr) return rhs->val < lhs->val;
if (rhs != nullptr) return true;
else return false;
}
};
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
ListNode dummy;
ListNode* node = &dummy;
priority_queue<ListNode*, vector<ListNode*>, MyCmp> queue (lists.begin(), lists.end());
while (!queue.empty() && queue.top() != nullptr) {
node = node->next = queue.top();
queue.pop();
if (node->next != nullptr) queue.push(node->next);
}
return dummy.next;
}
};
215
维护一个长度为k
的优先队列,并从小到大排列,如果新元素比头部元素大,头部元素不再是前k
大,弹出,不断更新即可,最后头元素即是第k
大
class Solution {
public:
int findKthLargest(vector<int>& nums, int k) {
priority_queue<int, vector<int>, greater<>> q;
for (const auto &num: nums) {
if (q.size() < k) {
q.push(num);
} else if (q.top() < num) {
q.pop();
q.push(num);
}
}
return q.top();
}
};
264 丑数II
已知丑数的构成:丑数=丑数*2/3/5,第一个丑数是1,则递推生成即可(dp)。有序的生成丑数,需要每次在生成的丑数中选择最小的丑数,来生成新的丑数,所以需要维护一个优先队列(小顶堆),生成新的丑数后,原来的丑数出队;如果堆顶的丑数重复,则直接出队。
class Solution {
public:
int nthUglyNumber(int n) {
priority_queue<long, vector<long>, greater<long> >q;
q.push(1);
long* arr = new long[n];
for (int i = 0; i < n; i++) {
arr[i] = q.top();
q.pop();
q.push(arr[i] * 2);
q.push(arr[i] * 3);
q.push(arr[i] * 5);
while (q.top() == arr[i]) {
q.pop();
}
}
return arr[n - 1];
}
};