From 3617a14eb6632fd7cd8b11360c0485b8b9c52a02 Mon Sep 17 00:00:00 2001 From: gameloader Date: Sun, 29 Sep 2024 10:22:21 +0800 Subject: [PATCH] leetcode update --- content/posts/leetcode.md | 84 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) diff --git a/content/posts/leetcode.md b/content/posts/leetcode.md index 493fb8c..e393aec 100644 --- a/content/posts/leetcode.md +++ b/content/posts/leetcode.md @@ -14445,3 +14445,87 @@ public: }; ``` + +## day215 2024-09-29 + +### 432. All O`one Data Structure + +Design a data structure to store the strings' count with the ability to return the strings with minimum and maximum counts. + +Implement the AllOne class: + +AllOne() Initializes the object of the data structure. +inc(String key) Increments the count of the string key by 1. If key does not exist in the data structure, insert it with count 1. +dec(String key) Decrements the count of the string key by 1. If the count of key is 0 after the decrement, remove it from the data structure. It is guaranteed that key exists in the data structure before the decrement. +getMaxKey() Returns one of the keys with the maximal count. If no element exists, return an empty string "". +getMinKey() Returns one of the keys with the minimum count. If no element exists, return an empty string "". +Note that each function must run in O(1) average time complexity. + +![0929ecisQ42xBcws](https://testingcf.jsdelivr.net/gh/game-loader/picbase@master/uPic/0929ecisQ42xBcws.png) + +### 题解 + +本题是一道难题,本题要快速获得出现频率最大的key和出现频率最小的key,就要将频率和对应的key记录下来。一方面我们要记录每个key和其对应的频率方便进行增减操作,即尽快完成inc和dec操作,另一方面我们也要记录不同频率和其对应的keys以便快速查找最大最小频率对应的key。记录每个key和其对应的频率可以通过map(可以使用unordered map,因为顺序不重要)实现,记录频率和其对应的key也可以通过map实现,区别在于因为一个频率可能对应多个字符串,则map需要将频率作为键,将一个字符串set作为值方便快速插入和删除该频率对应的字符串中的某个字符串。由于map默认是有序的,则找到最大值和最小值只需返回map的开头和结尾set中任一字符串即可。 + +在增加某个key时,如果该key不存在,则插入这个key并将频率设置为1,同时查询频率map,若频率map中不存在1这个key,则插入1作为key,并在对应的set中插入这个字符串。存在则直接插入字符串。若增加的key存在,则在频率map中找到以对应频率为key的set,删掉这个字符串,并找频率+1对应的set,将这个字符串插入。减少某个key类似。获取最大最小key直接找到频率map的begin和rbegin,即有序map的开头和结尾返回set中任一字符串即可。 + +注意如果将map和set的查询,删除,插入操作都视为均摊时间复杂度为O(1)的话,则本题我们实现的四个函数的时间复杂度可以视为O(1),满足题目条件。 + +### 代码 + +```cpp +class AllOne { +private: + unordered_map strmaps; + map> fre; +public: + AllOne() { + } + + void inc(string key) { + // 如果 key 不存在,插入并设置频率为 1 + if (strmaps.find(key) == strmaps.end()) { + strmaps[key] = 1; + fre[1].insert(key); + } else { + int count = strmaps[key]; + strmaps[key]++; + fre[count].erase(key); + if (fre[count].empty()) { + fre.erase(count); + } + fre[count + 1].insert(key); + } + } + + void dec(string key) { + int count = strmaps[key]; + strmaps[key]--; + fre[count].erase(key); + + if (fre[count].empty()) { + fre.erase(count); + } + + if (strmaps[key] == 0) { + strmaps.erase(key); + } else { + fre[count - 1].insert(key); + } + } + + string getMaxKey() { + if (fre.empty()) { + return ""; + } + return *(fre.rbegin()->second.begin()); + } + + string getMinKey() { + if (fre.empty()) { + return ""; + } + return *(fre.begin()->second.begin()); + } +}; +```