0
点赞
收藏
分享

微信扫一扫

432.全 O(1) 的数据结构

云岭逸人 2022-03-16 阅读 79
数据结构

题目

432.全 O(1) 的数据结构

题目大意

请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。

实现 AllOne 类:

  • AllOne() 初始化数据结构的对象。
  • inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1key
  • dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。
  • getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 ""
  • getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 ""

样例

image-20220316100338489

数据规模

提示:

  • 1 <= key.length <= 10
  • key 由小写英文字母组成
  • 测试用例保证:在每次调用 dec 时,数据结构中总存在 key
  • 最多调用 incdecgetMaxKeygetMinKey 方法 5 ∗ 1 0 4 5 * 10^4 5104

思路

观察数据规模:最多调用 incdecgetMaxKeygetMinKey 方法 5 ∗ 1 0 4 5 * 10^4 5104 次。那么实际上设计出 O ( n l o g n ) O(nlogn) O(nlogn)的算法就可以完成本题(当然如果需要更优秀的算法,比如十字链表,还请查看别的博客)。

考虑使用优先队列:使用大根堆和小根堆保存(数量, 字符串)的映射,用数量作为排序的键。

  • 增加和删除的时候,把当前的新版本的(数量,字符串)放入队列中。这样队列中保存的就是新版本和老版本的(数量, 字符串)。
  • 问的时候,进行懒删除: 如果当前的队头元素不是最新的元素(mp[s]==num(auto [num,s]=q.top()))就删除;如果该元素是最新的,就直接使用,并且不删除。
  • 如果数量等于 0 0 0,就不用放入队列中;否则需要再访问的时候,判断是否为0。

代码

// short int long float double bool char string void
// array vector stack queue auto const operator
// class public private static friend extern 
// sizeof new delete return cout cin memset malloc
// relloc size length memset malloc relloc size length
// for while if else switch case continue break system
// endl reverse sort swap substr begin end iterator
// namespace include define NULL nullptr exit equals 
// index col row arr err left right ans res vec que sta
// state flag ch str max min default charray std
// maxn minn INT_MAX INT_MIN push_back insert
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int>PII;
typedef pair<int, string>PIS;
const int maxn=1e6+50;//注意修改大小
long long read(){long long x=0,f=1;char c=getchar();while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}while(isdigit(c)){x=x*10+c-'0';c=getchar();}return x*f;}
ll qpow(ll x,ll q,ll Mod){ll ans=1;while(q){if(q&1)ans=ans*x%Mod;q>>=1;x=(x*x)%Mod;}return ans%Mod;}


class AllOne {
public:
    unordered_map<string,int>mp;
    priority_queue<PIS,vector<PIS>,greater<PIS>>lq;
    priority_queue<PIS>gq;
    AllOne() {
        mp.clear();
    }
    
    void inc(string key) {
        mp[key]++;
        lq.push({mp[key],key});
        gq.push({mp[key],key});
    }
    
    void dec(string key) {
        mp[key]--;
        if(mp[key]==0)return ;
        lq.push({mp[key],key});
        gq.push({mp[key],key});
    }
    
    string getMaxKey() {
        while(gq.size()){
            auto [num,s]=gq.top();
            if(mp[s]==num)return s;
            gq.pop();
        }
        return "";
    }
    
    string getMinKey() {
        while(lq.size()){
            auto [num,s]=lq.top();
            if(mp[s]==num)return s;
            lq.pop();
        }
        return "";
    }
};

/**
 * Your AllOne object will be instantiated and called as such:
 * AllOne* obj = new AllOne();
 * obj->inc(key);
 * obj->dec(key);
 * string param_3 = obj->getMaxKey();
 * string param_4 = obj->getMinKey();
 */
举报

相关推荐

0 条评论