432. All O`one Data Structure
Implement a data structure supporting the following operations:
""
.""
.
Challenge: Perform all these in O(1) time complexity.
实现一个数据结构,满足对一个key的value加1、减,求所有key最大值和最小值,要求所有操作均为O(1)实现。
思路:
围绕所有操作均为O(1)展开,数据结构可选一定为unordered_map和list,map里面存放key对应list的指针,list里面元素为一个值为val的set
代码:
class AllOne {
public:
struct bucket {
int val;
unordered_set s;
};
unordered_map::iterator> mp;
list li;
list::iterator it;
/** Initialize your data structure here. */
AllOne() {
}
/** Inserts a new key with value 1. Or increments an existing key by 1. */
void inc(string key) {
if (mp.find(key) != mp.end()) {
it = mp[key];
list::iterator nextit = it;
nextit++;
if (nextit == li.end()||nextit->val!=it->val + 1) {
bucket tmp;
tmp.val = it->val + 1;
tmp.s.insert(key);
mp[key] = li.insert(nextit, tmp);
} else {
nextit->s.insert(key);
mp[key] = nextit;
}
//delete it
if (it->s.size() == 1) {
li.erase(it);
} else {
it->s.erase(key);
}
} else {
if (li.size() && li.front().val == 1) {
li.front().s.insert(key);
mp[key] = li.begin();
} else {
bucket tmp;
tmp.val = 1;
tmp.s.insert(key);
it = li.insert(li.begin(), tmp);
mp[key] = it;
}
}
}
/** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
void dec(string key) {
if (mp.find(key) == mp.end()) return;
it = mp[key];
if (it->val == 1) {
it->s.erase(key);
if (it->s.size() == 0) li.erase(it);
mp.erase(key);
return;
}
list::iterator previt = it;
previt--;
if (it == li.begin() || previt->val + 1 != it->val) {
bucket tmp;
tmp.val = it->val - 1;
tmp.s.insert(key);
mp[key] = li.insert(it, tmp);
} else {
previt->s.insert(key);
mp[key] = previt;
}
//delete it
if (it->s.size() == 1) {
li.erase(it);
} else {
it->s.erase(key);
}
}
/** Returns one of the keys with maximal value. */
string getMaxKey() {
if (li.size()) return *li.back().s.begin();
return "";
}
/** Returns one of the keys with Minimal value. */
string getMinKey() {
if (li.size()) return *li.front().s.begin();
return "";
}
};
python版本,双向链表需要手动实现
class node:
def __init__(self,value=0,key=0):
self.value=value
self.keys=set([key])
self.prev=None
self.next=None
def __str__(self):
return ("%d:%s") % (self.value, str(self.keys))
class MyList:
def __init__(self):
self.head=node()
self.tail=node()
self.head.next=self.tail
self.tail.prev=self.head
def push_front(self,node):
node.next=self.head.next
node.prev=self.head
self.head.next.prev = node
self.head.next=node
def push_back(self,node):
node.prev=self.tail.prev
node.next=self.tail
self.tail.prev.next=node
self.tail.prev=node
def insert(self,posnode,node):
node.next=posnode.next
node.prev = posnode
posnode.next.prev= node
posnode.next=node
def eraser(self,node):
node.prev.next=node.next
node.next.prev=node.prev
del node
def view(self):
p=self.head
while p!=None:
print p,"->",
p=p.next
print ""
def view2(self):
p=self.tail
while p!=None:
print p,"->",
p=p.prev
print ""
class AllOne(object):
def __init__(self):
"""
Initialize your data structure here.
"""
self.li=MyList()
self.di=dict()
def inc(self, key):
"""
Inserts a new key with value 1. Or increments an existing key by 1.
:type key: str
:rtype: void
"""
# import pdb
# pdb.set_trace()
ha=self.di.get(key,None)
if ha and len(ha.keys)>0:
if ha.next!=self.li.tail and ha.next.value==ha.value+1:
ha.next.keys.add(key)
self.di[key] = ha.next
else:
cur = node(ha.value + 1, key)
self.li.insert(ha,cur)
self.di[key] = cur
ha.keys.remove(key)
if len(ha.keys)==0:
self.li.eraser(ha)
else:
if self.li.head.next and self.li.head.next.value==1:
self.li.head.next.keys.add(key)
self.di[key]=self.li.head.next
else:
cur=node(1,key)
self.li.push_front(cur)
self.di[key] = cur
def dec(self, key):
"""
Decrements an existing key by 1. If Key's value is 1, remove it from the data structure.
:type key: str
:rtype: void
"""
# import pdb
# pdb.set_trace()
ha = self.di.get(key, None)
if ha:
if ha.value>1:
if ha.prev != self.li.head and ha.prev.value == ha.value - 1:
ha.prev.keys.add(key)
self.di[key] = ha.prev
else:
cur = node(ha.value - 1, key)
self.li.insert(ha.prev,cur)
self.di[key] = cur
else:
self.di.pop(key)
# print "before remove"
# self.li.view()
ha.keys.remove(key)
if len(ha.keys) == 0:
self.li.eraser(ha)
# print "after remove"
# self.li.view()
def getMaxKey(self):
"""
Returns one of the keys with maximal value.
:rtype: str
"""
if self.li.tail==self.li.head.next:
return ""
it=iter(self.li.tail.prev.keys)
return it.next()
def getMinKey(self):
"""
Returns one of the keys with Minimal value.
:rtype: str
"""
if self.li.tail==self.li.head.next:
return ""
it=iter(self.li.head.next.keys)
return it.next()