题目:

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。
pop() -- 从队列首部移除元素。
peek() -- 返回队列首部的元素。
empty() -- 返回队列是否为空。
注意: 你只能使用标准的栈操作-- 也就是只有push to top, peek/pop from top, size, 和 is empty 操作是合法的。
你所使用的语言也许不支持栈。你可以使用 list 或者 deque (双端队列) 来模拟一个栈,只要是标准的栈操作即可。
假设所有操作都是有效的 (例如,一个空的队列不会调用 pop 或者 peek 操作)。

本题解题思路:

思考过程中考虑到可以用两个map来解决该问题,但发现比较麻烦,后自己写了一个解决方案:

核心数据结构:

struct DoubleListNode{
void * val;
DoubleListNode * pre;
DoubleListNode * next;
DoubleListNode(void * x):val(x){
pre = NULL;
next = NULL;
}
}; struct StrToken{
int counter;
set<string> strs;
};

用一个排序的双向链表来存储所有的key和key的计数,数列的计数从小到大。

如果返回最小计数的key,则返回队列中的头元素,如果返回最大计数的key,则返回队列的最末位的元素;

插入元素:

如果发现该key已经存在map中,则找到该节点,将该key插入到其计算加1的链表节点中去,同时更新map映射;如果发现该key不存在,则将该key插入到计算为1的节点中去,同时更新map映射。

删除元素:

如果发现该key已经存在map中,则找到该节点,将该key插入到其计算减一的链表节点中去同时更新MAP映射。

返回最大值:

由于链表是按照计算的大小排列的,返回链表中的最后端的元素即可。

返回最小值:

由于链表是按照计算的大小排列的,返回链表中的最前端的元素即可。

源代码如下,leetcode执行时间为40ms

struct DoubleListNode{
void * val;
DoubleListNode * pre;
DoubleListNode * next;
DoubleListNode(void * x):val(x){
pre = NULL;
next = NULL;
}
}; struct StrToken{
int counter;
set<string> strs;
}; class DoubleLinkList{
public:
DoubleLinkList(){
head = new DoubleListNode(NULL);
tail = new DoubleListNode(NULL);
head->next = tail;
tail->pre = head;
cnt = ;
} bool insertHead(DoubleListNode * node){
if(NULL == node || NULL == head){
return false;
} node->next = head->next;
node->pre = head;
head->next->pre = node;
head->next = node;
cnt++; return true;
} bool insertTail(DoubleListNode * node){
if(NULL == node || NULL == tail){
return false;
} node->next = tail;
node->pre = tail->pre;
tail->pre->next = node;
tail->pre = node;
cnt++; return true;
} DoubleListNode * getHead(){
return this->head;
} DoubleListNode * getTail(){
return this->tail;
} DoubleListNode * getNext(const DoubleListNode * target){
if(NULL == target){
return NULL;
} return target->next;
} DoubleListNode * getPrev(const DoubleListNode * target){
if(NULL == target){
return NULL;
} return target->pre;
} bool isHead(const DoubleListNode * target){
if(head == target){
return true;
}else{
return false;
}
} bool isTail(const DoubleListNode * target){
if(tail == target){
return true;
}else{
return false;
}
} bool deleteTarget(DoubleListNode * node){
if(NULL == node || node == head || node == tail){
return false;
} if(!node->pre || !node->next){
return false;
} node->pre->next = node->next;
node->next->pre = node->pre; node->next = NULL;
node->pre = NULL;
if(node->val){
delete node->val;
node->val = NULL;
} delete node;
node = NULL; return true;
} bool insertBefore(DoubleListNode * target,DoubleListNode * node){
if(NULL == target || NULL == node){
return false;
} node->pre = target->pre;
node->next = target;
target->pre->next = node;
target->pre = node;
cnt++; return true;
} bool insertAfter(DoubleListNode * target,DoubleListNode * node){
if(NULL == target || NULL == node){
return false;
} node->pre = target;
node->next = target->next;
target->next->pre = node;
target->next = node;
cnt++; return true;
} int length(){
return cnt;
} bool isEmpty(){
if(head->next == tail){
return true;
}else{
return false;
}
} private:
struct DoubleListNode * head;
struct DoubleListNode * tail;
int cnt;
}; class AllOne {
public:
/** Initialize your data structure here. */
AllOne() { } /** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
void inc(string key) {
if(keyMap.find(key) == keyMap.end()){
/*we wiil insert the first node*/
DoubleListNode * head = keyList.getHead();
DoubleListNode * next = keyList.getNext(head);
StrToken * toke = (StrToken *)(next->val); /*we will add a new node in to the linklist*/
if(keyList.isEmpty() || (toke != NULL && toke->counter > )){
StrToken * newToke = new StrToken();
newToke->counter = ;
newToke->strs.insert(key);
DoubleListNode * newNode = new DoubleListNode(newToke);
keyList.insertHead(newNode);
keyMap[key] = newNode;
}else{/*we add the key in to the token*/
if( NULL != toke && toke->counter == ){
toke->strs.insert(key);
keyMap[key] = next;
}
}
}else{
map<string,DoubleListNode *>::iterator it = keyMap.find(key);
DoubleListNode * node = it->second;
StrToken * toke = (StrToken *)(node->val);
toke->strs.erase(key);
DoubleListNode * next = keyList.getNext(node);
StrToken * nextToke = NULL;
if(next != keyList.getTail()){
nextToke = (StrToken *)(next->val);
} if(next == keyList.getTail() ||
(nextToke!=NULL && nextToke->counter > (toke->counter+))){
StrToken * newToke = new StrToken();
newToke->counter = toke->counter+;
newToke->strs.insert(key);
DoubleListNode * newNode = new DoubleListNode(newToke);
keyList.insertAfter(node,newNode);
keyMap[key] = newNode;
}else{
if(nextToke){
nextToke->strs.insert(key);
keyMap[key] = next;
}
} if(toke->strs.empty()){
keyList.deleteTarget(node);
}
} //debug();
} /** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
void dec(string key) {
if(keyMap.find(key) == keyMap.end()){
return;
} map<string,DoubleListNode *>::iterator it = keyMap.find(key);
DoubleListNode * node = it->second;
StrToken * toke = (StrToken *)(node->val);
toke->strs.erase(key);
DoubleListNode * prev = keyList.getPrev(node);
StrToken * prevToke = NULL;
if(prev != keyList.getHead()){
prevToke = (StrToken *)(prev->val);
} if(toke->counter > ){
if(prev == keyList.getHead() ||
(prevToke!=NULL && prevToke->counter < (toke->counter - ))){
StrToken * newToke = new StrToken();
newToke->counter = toke->counter - ;
newToke->strs.insert(key);
DoubleListNode * newNode = new DoubleListNode(newToke);
keyList.insertBefore(node,newNode);
keyMap[key] = newNode;
}else{
if(prevToke){
prevToke->strs.insert(key);
keyMap[key] = prev;
}
}
}else{
keyMap.erase(key);
} if(toke->strs.empty()){
keyList.deleteTarget(node);
} //debug();
} /** Returns one of the keys with maximal value. */
string getMaxKey() {
string res;
if(keyList.isEmpty()){
return res;
} DoubleListNode * node = keyList.getPrev(keyList.getTail());
StrToken * toke = (StrToken *)(node->val);
return *(toke->strs.begin());
} /** Returns one of the keys with Minimal value. */
string getMinKey() {
string res;
if(keyList.isEmpty()){
return res;
} DoubleListNode * node = keyList.getNext(keyList.getHead());
StrToken * toke = (StrToken *)(node->val);
return *(toke->strs.begin());
} void debug(){
cout<<endl;
DoubleListNode * node = keyList.getNext(keyList.getHead());
for(;node!=keyList.getTail();node = keyList.getNext(node)){
StrToken * toke = (StrToken *)(node->val);
cout<<"cnt:"<<toke->counter<<endl;
set<string>::iterator it = toke->strs.begin();
for(;it!=toke->strs.end();++it){
cout<<*it<<" ";
}
cout<<endl;
}
} private:
map<string,DoubleListNode *> keyMap;
DoubleLinkList keyList;
}; /**
* 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();
*/

【系统设计】432. 全 O(1) 的数据结构的更多相关文章

  1. Java实现 LeetCode 432 全 O(1) 的数据结构

    432. 全 O(1) 的数据结构 实现一个数据结构支持以下操作: Inc(key) - 插入一个新的值为 1 的 key.或者使一个存在的 key 增加一,保证 key 不为空字符串. Dec(ke ...

  2. [LeetCode] All O`one Data Structure 全O(1)的数据结构

    Implement a data structure supporting the following operations: Inc(Key) - Inserts a new key with va ...

  3. leetcode难题

    4 寻找两个有序数组的中位数       35.9% 困难     10 正则表达式匹配       24.6% 困难     23 合并K个排序链表       47.4% 困难     25 K ...

  4. C#LeetCode刷题-设计

    设计篇 # 题名 刷题 通过率 难度 146 LRU缓存机制   33.1% 困难 155 最小栈 C#LeetCode刷题之#155-最小栈(Min Stack) 44.9% 简单 173 二叉搜索 ...

  5. Pandas_基础_全

    Pandas基础(全) 引言 Pandas是基于Numpy的库,但功能更加强大,Numpy专注于数值型数据的操作,而Pandas对数值型,字符串型等多种格式的表格数据都有很好的支持. 关于Numpy的 ...

  6. Python全栈之路----目录

    Module1 Python基本语法 Python全栈之路----编程基本情况介绍 Python全栈之路----常用数据类型--集合 Module2 数据类型.字符编码.文件操作 Python全栈之路 ...

  7. 《数据结构-C语言版》(严蔚敏,吴伟民版)课本源码+习题集解析使用说明

    <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明 先附上文档归类目录: 课本源码合辑  链接☛☛☛ <数据结构>课本源码合辑 习题集全解析  链接☛☛☛  ...

  8. 9-11-Trie树/字典树/前缀树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第9章  查找 - Trie树/字典树/前缀树(键树) ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚 ...

  9. 9-9-B+树-查找-第9章-《数据结构》课本源码-严蔚敏吴伟民版

    课本源码部分 第9章  查找 - B+树 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接☛☛☛ <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题 ...

随机推荐

  1. selenium自动化之显式等待和EC(expected_conditions)模块

    很多人都有这种经历,selenium脚本当前运行没问题,过了一段时间再运行就报错了,然后过几天又好了.其中的原因估计60%的人都知道,是因为元素加载这块有问题.通常的解决方案就是加上sleep或者隐式 ...

  2. myeclipse tomcat部署按钮点击没反应

    进入workspace目录,删除.metadata\.plugins\org.eclipse.core.runtime\.settings\com.genuitec.eclipse.ast.deplo ...

  3. spark相关脚本解析

    spark-shell/spark-submit/pyspark等关系如下: #spark-submit 逻辑: ########################################### ...

  4. yarn logs -applicationId命令java版本简单实现

    import java.io.DataInputStream; import java.io.EOFException; import java.io.FileNotFoundException; i ...

  5. CDH问题集

    1.在CM中添加主机报JDK错误 手动在机器上安装oracle-jdk1.7+update64.然后在CM中选择不安装oracle-jdk即可. 2.HostMoinitor无法与server联系 查 ...

  6. [leetcode-667-Beautiful Arrangement II]

    Given two integers n and k, you need to construct a list which contains n different positive integer ...

  7. Beta阶段项目展示博客

    Beta阶段项目展示 团队成员的简介 详细见团队简介 角色 姓名 照片 项目经理,策划 游心 策划 王子铭 策划 蔡帜 美工 赵晓宇 美工 王辰昱 开发.架构师 解小锐 开发 陈鑫 开发 李金奇 开发 ...

  8. spring框架(1)— 依赖注入

    依赖注入 spring核心容器就是一个超级大工厂,所以的对象(数据源.hibernate SessionFactory等基础性资源)都会被当做spring核心容器的管理对象——spring把容器中的一 ...

  9. ALPHA-3

    前言 失心疯病源3 团队代码管理github 站立会议 队名:PMS 530雨勤(组长) 今天完成了那些任务 16:00~20:18 援助行人模块并确定最终框架,顺便不死心的又找了一波车辆检测的dem ...

  10. Swift-创建UIButton(其他UI组件雷同)

    let button = UIButton.init(frame: CGRectMake(, , , )) button.setTitle("按钮", forState: UICo ...