从Leetcode学到的STL用法

priority_queue

优先队列priority_queue
头文件 #include

priority_queue < int >默认构建的是一个大根堆,所以每次从头取数据得到的是一个从大到小的队列排序.
priority_queue< int> 实际上等价于 priority_queue<int, vector, less< int>>。
top是最大的值
小根堆: priority_queue<int, vector< int>, greater< int>> q; top是最小的值

实现自己的最大堆

class mypriority_queue
{
private:
    vector<int> keep;
public:
    // mypriority_queue(/* args */);
    // ~mypriority_queue();

    void Push(int value){
        keep.push_back(value);
        int keepSize = keep.size()-1;
        int parent = (keepSize-1)/2;
        while(parent>=0 && keep[keepSize] > keep[parent]){
            swap(keep[keepSize], keep[parent]);
            keepSize = parent;
            parent = (keepSize-1)/2;
        }
        return;
    }

    void Pop(){
        int tmp = keep.back();
        swap(tmp, keep[0]);
        keep.pop_back();
        int top = 0;
        int son = top * 2 + 1; // right孩子
        while(son < keep.size()){
            if(son +1 < keep.size() && keep[son+1] > keep[son]){
                if(keep[top] < keep[son+1]){
                    swap(keep[top], keep[son+1]);
                    top = son + 1;
                    son = top*2 + 1;
                }else{
                    break;
                }
            }else{
                if(keep[top] < keep[son]){
                    swap(keep[top], keep[son]);
                    top = son;
                    son = top*2 + 1;
                }else{
                    break;
                }
            }
        }
        return;
    }

    int Top() const{
        return keep[0];
    }

    int Empty() const{
        return keep.empty();
    }

    friend ostream &operator<<(ostream &os, const mypriority_queue &mypq){
        for(const auto aa : mypq.keep){
            cout<<aa<<" ";
        }
        cout<<endl;
        return os;
    }
};

用法演示

// 基础用法
class Solution {
public:
    int findKthLargest(vector<int>& nums, int k) {
        priority_queue<int, vector< int>, greater< int>>  aa;

        for(int i = 0; i< nums.size(); i++)
        {
            if(aa.size() < k)
            {
                aa.push(nums[i]);
            }else if(nums[i] > aa.top()){
                aa.pop();
                aa.push(nums[i]);
            }
        }
        return aa.top();
        
    }
};

// 自定义用法
#include<iostream>
#include <queue>
using namespace std;
int main()
{
    //对于基础类型 默认是大顶堆
    priority_queue<int> a;
    //等同于 priority_queue<int, vector<int>, less<int> > a;
 
    //      这里一定要有空格,不然成了右移运算符↓↓
    priority_queue<int, vector<int>, greater<int> > c;  //这样就是小顶堆
    priority_queue<string> b;
 
    for (int i = 0; i < 5; i++)
    {
        a.push(i);
        c.push(i);
    }
    while (!a.empty())
    {
        cout << a.top() << ' ';
        a.pop();
    }
    cout << endl;
 
    while (!c.empty())
    {
        cout << c.top() << ' ';
        c.pop();
    }
    cout << endl;
 
    b.push("abc");
    b.push("abcd");
    b.push("cbd");
    while (!b.empty())
    {
        cout << b.top() << ' ';
        b.pop();
    }
    cout << endl;
    return 0;
}


#include <iostream>
#include <queue>
using namespace std;
 
//方法1
struct tmp1 //运算符重载<
{
    int x;
    tmp1(int a) {x = a;}
    bool operator<(const tmp1& a) const
    {
        return x < a.x; //大顶堆
    }
};
 
//方法2
struct tmp2 //重写仿函数
{
    bool operator() (tmp1 a, tmp1 b)
    {
        return a.x < b.x; //大顶堆
    }
};
 
int main()
{
    tmp1 a(1);
    tmp1 b(2);
    tmp1 c(3);
    priority_queue<tmp1> d;
    d.push(b);
    d.push(c);
    d.push(a);
    while (!d.empty())
    {
        cout << d.top().x << '\n';
        d.pop();
    }
    cout << endl;
 
    priority_queue<tmp1, vector<tmp1>, tmp2> f;
    f.push(b);
    f.push(c);
    f.push(a);
    while (!f.empty())
    {
        cout << f.top().x << '\n';
        f.pop();
    }
}

multiset

MultiSet和Set的区别:

1) MultiSet

  可以插入完全相同的两条记录

  会提高数据插入的速度

2) Set

  不可以插入完全相同的两条记录

  保证记录的唯一性

  由于需要查重处理,会降低数据插入的速度

  可以作为一种去重的方法

用法演示

你可以安排的最多任务数目

给你 n 个任务和 m 个工人。每个任务需要一定的力量值才能完成,需要的力量值保存在下标从 0 开始的整数数组 tasks 中,第 i 个任务需要 tasks[i] 的力量才能完成。每个工人的力量值保存在下标从 0 开始的整数数组 workers 中,第 j 个工人的力量值为 workers[j] 。每个工人只能完成 一个 任务,且力量值需要 大于等于 该任务的力量要求值(即 workers[j] >= tasks[i] )。

除此以外,你还有 pills 个神奇药丸,可以给 一个工人的力量值 增加 strength 。你可以决定给哪些工人使用药丸,但每个工人 最多 只能使用 一片 药丸。

给你下标从 0 开始的整数数组tasks 和 workers 以及两个整数 pills 和 strength ,请你返回 最多 有多少个任务可以被完成。

C++ lower_bound()函数
lower_bound() 函数用于在指定区域内查找不小于目标值的第一个元素。也就是说,使用该函数在指定范围内查找某个目标值时,最终查找到的不一定是和目标值相等的元素,还可能是比目标值大的元素。


class Solution {
public:
    int maxTaskAssign(vector<int>& tasks, vector<int>& workers, int pills, int strength) {
        int n = tasks.size(), m = workers.size();
        sort(tasks.begin(), tasks.end());
        sort(workers.begin(), workers.end());
        
        auto check = [&](int mid) -> bool {
            int p = pills;
            // 工人的有序集合
            multiset<int> ws;
            for (int i = m - mid; i < m; ++i) {
                ws.insert(workers[i]);
            }
            // 从大到小枚举每一个任务
            for (int i = mid - 1; i >= 0; --i) {
                // 如果有序集合中最大的元素大于等于 tasks[i]
                if (auto it = prev(ws.end()); *it >= tasks[i]) {
                    ws.erase(it);
                }
                else {
                    if (!p) {
                        return false;
                    }
                    auto rep = ws.lower_bound(tasks[i] - strength);
                    if (rep == ws.end()) {
                        return false;
                    }
                    --p;
                    ws.erase(rep);
                }
            }
            return true;
        };
        
        int left = 1, right = min(m, n), ans = 0;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (check(mid)) {
                ans = mid;
                left = mid + 1;
            }
            else {
                right = mid - 1;
            }
        }
        return ans;
    }
};

unordered_set

统计字符串中的元音子字符串

头文件 #include<unordered_set>

unordered_set可以把它想象成一个集合,它提供了几个函数让我们可以增删查:
unordered_set::insert
unordered_set::find
unordered_set::erase

用法演示

class Solution {
public:
    int countVowelSubstrings(string word) {
        int n = word.size();
        int res = 0;
        unordered_set<char> vowelset = {'a', 'e', 'i', 'o', 'u'};   // 所有元音对应的哈希集合
        for (int i = 0; i < n; ++i){
            // 枚举左端点
            unordered_set<char> charset;   // 子串对应的哈希集合
            for (int j = i; j < n; ++j){
                // 按顺序枚举右端点并更新子串哈希集合及比较
                charset.insert(word[j]);
                if (charset == vowelset){
                    ++res;
                }
            }
        }
        return res;
    }
};

map 和 unordered_map

需要引入的头文件不同
map: #include < map >
map 由红黑树实现的已排序
unordered_map: #include < unordered_map >
无重复key,未排序的哈希表

用法演示

从英文中重建数字

给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)。按 升序 返回原始的数字。

class Solution {
public:
    string originalDigits(string s) {
        unordered_map<char, int> c;
        for (char ch: s) {
            ++c[ch];
        }

        vector<int> cnt(10);
        cnt[0] = c['z'];
        cnt[2] = c['w'];
        cnt[4] = c['u'];
        cnt[6] = c['x'];
        cnt[8] = c['g'];

        cnt[3] = c['h'] - cnt[8];
        cnt[5] = c['f'] - cnt[4];
        cnt[7] = c['s'] - cnt[6];

        cnt[1] = c['o'] - cnt[0] - cnt[2] - cnt[4];

        cnt[9] = c['i'] - cnt[5] - cnt[6] - cnt[8];

        string ans;
        for (int i = 0; i < 10; ++i) {
            for (int j = 0; j < cnt[i]; ++j) {
                ans += char(i + '0');
            }
        }
        return ans;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值