LeetCode-432 全O(1)的数据结构
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/all-oone-data-structure
题目描述
请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。
实现 AllOne 类:
AllOne() 初始化数据结构的对象。
inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key 。
dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。
getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 "" 。
getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 "" 。
示例:
输入
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
输出
[null, null, null, "hello", "hello", null, "hello", "leet"]
解释
AllOne allOne = new AllOne();
allOne.inc("hello");
allOne.inc("hello");
allOne.getMaxKey(); // 返回 "hello"
allOne.getMinKey(); // 返回 "hello"
allOne.inc("leet");
allOne.getMaxKey(); // 返回 "hello"
allOne.getMinKey(); // 返回 "leet"
提示:
1 <= key.length <= 10
key 由小写英文字母组成
测试用例保证:在每次调用 dec 时,数据结构中总存在 key
最多调用 inc、dec、getMaxKey 和 getMinKey 方法 5 * 104 次
解题思路
题目难点在于要将操作的时间复杂度全部变为O(1),对于修改来说,很容易想到哈希表,但是哈希表的查询最大值最小值的时间复杂度并不是O(1),查询最大值和最小值的时间复杂度为O(1)的很容易想到优先队列,但是优先队列的修改时间复杂度并不是O(1),所以,这里使用一个递增的双向链表来记录所有数据,当查询最小值返回链表头,查询最大值返回链表尾,并且通过哈希表将链表结点和key值绑定,使得修改时候可以在O(1)时间内找到结点,结点内容存储的是一个set,这样可以将相同计数的结点合成一个结点,将修改的过程缩短到O(1)的时间复杂度。注意在修改时候,分类处理未出现过的key和已出现的key,还有计数为0的key。
代码展示
class AllOne {
public:
list<pair<unordered_set<string>, int>> NodeList;
unordered_map<string, list<pair<unordered_set<string>, int>>::iterator> mapstriterMap;
AllOne() { } void inc(string key) {
if(mapstriterMap.count(key))
{
auto curIter = mapstriterMap[key];
auto nextIter = next(curIter);
if(nextIter == NodeList.end() || curIter->second + 1 < nextIter->second)
{
unordered_set<string> node{key};
mapstriterMap[key] = NodeList.emplace(nextIter, node, curIter->second + 1);
}
else
{
nextIter->first.emplace(key);
mapstriterMap[key] = nextIter;
}
curIter->first.erase(key);
if(curIter->first.empty())
NodeList.erase(curIter);
}
else
{
if(NodeList.empty() || NodeList.begin()->second != 1)
{
unordered_set<string> node{key};
NodeList.emplace_front(node, 1);
}
else
{
NodeList.begin()->first.emplace(key);
}
mapstriterMap[key] = NodeList.begin();
}
} void dec(string key) {
if(mapstriterMap.count(key))
{
auto curIter = mapstriterMap[key];
auto prevIter = prev(curIter);
if(curIter == NodeList.begin())
{
if(curIter->second - 1 <= 0)
{
mapstriterMap.erase(key);
}
else
{
unordered_set<string> node{key};
NodeList.emplace_front(node, curIter->second - 1);
mapstriterMap[key] = NodeList.begin();
}
}
else if(curIter->second - 1 > prevIter->second)
{
unordered_set<string> node{key};
mapstriterMap[key] = NodeList.emplace(curIter, node, curIter->second - 1);
}
else
{
prevIter->first.emplace(key);
mapstriterMap[key] = prevIter;
}
curIter->first.erase(key);
if(curIter->first.empty())
NodeList.erase(curIter);
}
} string getMaxKey() {
return NodeList.empty()? "" : *NodeList.rbegin()->first.begin();
} string getMinKey() {
return NodeList.empty()? "" : *NodeList.begin()->first.begin();
}
}; /**
* 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();
*/
运行结果
LeetCode-432 全O(1)的数据结构的更多相关文章
- Java实现 LeetCode 432 全 O(1) 的数据结构
432. 全 O(1) 的数据结构 实现一个数据结构支持以下操作: Inc(key) - 插入一个新的值为 1 的 key.或者使一个存在的 key 增加一,保证 key 不为空字符串. Dec(ke ...
- 【系统设计】432. 全 O(1) 的数据结构
题目: 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- 返回队列首部的元素. empty() -- 返回队列是 ...
- [leetcode]432. All O`one Data Structure全O(1)数据结构
Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...
- [LeetCode] All O`one Data Structure 全O(1)的数据结构
Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...
- LeetCode Binary Tree Postorder Traversal(数据结构)
题意: 用迭代法输出一棵二叉树的后序遍历结果. 思路: (1)用两个栈,一个存指针,一个存标记,表示该指针当前已经访问过哪些孩子了. /** * Definition for a binary tre ...
- LeetCode Implement Stack using Queues (数据结构)
题意: 用队列来实现栈. 思路: 没有什么捷径,纯粹模拟.但是用一个队列就够了. class Stack { /* // Push element x onto stack. void push(in ...
- LeetCode Implement Queue using Stacks (数据结构)
题意: 用栈来实现队列. 思路: 一个栈是不够的,至少要两个. (1)插入.永远只插入到stack1中(插到栈顶). (2)弹出.如果stack2不为空,直接弹出stack2的栈顶,否则,将stack ...
- C#LeetCode刷题-设计
设计篇 # 题名 刷题 通过率 难度 146 LRU缓存机制 33.1% 困难 155 最小栈 C#LeetCode刷题之#155-最小栈(Min Stack) 44.9% 简单 173 二叉搜索 ...
- leetcode难题
4 寻找两个有序数组的中位数 35.9% 困难 10 正则表达式匹配 24.6% 困难 23 合并K个排序链表 47.4% 困难 25 K ...
- Pandas_基础_全
Pandas基础(全) 引言 Pandas是基于Numpy的库,但功能更加强大,Numpy专注于数值型数据的操作,而Pandas对数值型,字符串型等多种格式的表格数据都有很好的支持. 关于Numpy的 ...
随机推荐
- 体验 Gitea Actions
即将推出的 Gitea Actions 致力于打造一个 CI/CD 工具的标准协议,第三方 CI 系统可以基于actions 协议与 Gitea 平台集成,提供一站式管理方案.Gitea Action ...
- day03-功能实现02
家居网购项目实现02 5.功能04-会员登录 5.1需求分析/图解 需求如图: 输入用户名.密码后提交 判断该用户是否存在 如果存在,显示登录成功页面 否则返回登录页面,要求重新登录 要求改进登录密码 ...
- java逻辑运算中异或^
本文主要阐明逻辑运算符^(异或)的作用 a ^ b,相异为真,相同为假. 注意,异或运算,还能交换两个变量. int a = 1; int b = 2; System.out.println(&quo ...
- uniapp解析后端返回的html标签
<rich-text :nodes="data.content"></rich-text>
- 远程登录到Linux服务器
首先我们下载一个xshell,下载地址:https://www.xshell.com/zh/ 下载安装打开xshell 按快捷键alt + n进入新建窗口,输入自己的主机名,名称,说明等 双击点击左边 ...
- 基于SqlSugar的开发框架循序渐进介绍(24)-- 使用Serialize.Linq对Lambda表达式进行序列化和反序列化
在上篇随笔<基于SqlSugar的开发框架循序渐进介绍(23)-- Winform端管理系统中平滑增加对Web API对接的需求>中介绍了基于一个接口,实现对两种不同接入方式(直接访问数据 ...
- 推荐给Amy的书单
目录 皮囊 推荐等级 ※ ※ ※ ※ ※ 白夜行 推荐等级 ※ ※ ※ ※ ※ 人生 推荐等级 ※ ※ ※ ※ 活着 推荐等级 ※ ※ ※ ※ 许三观卖血记 推荐等级 ※ ※ ※ ※ 皮囊 推荐等级 ...
- HBase详解(03) - HBase架构和数据读写流程
RegionServer 架构 每个RegionServer可以服务于多个Region 每个RegionServer中有多个Store, 1个WAL和1个BlockCache 每个Store对应一个列 ...
- python网络爬虫数据解析之正则
本节内容,讲解爬取网络图片,利用正则匹配图片地址 请求网页之后,响应部分内容如下图: 1 时间:2023/1/7 10:42 2 功能描述 3 1.进行指定标签的定位 4 2.标签或者标签对应的属性中 ...
- mybatis-config.xml 说明
mybatis-config.xml 说明 文件结构 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息. 配置文档的顶层结构如下: configuration(配置) ...