【英雄算法六月集训】Day12
432. 全 O(1) 的数据结构
Hash+链表的方式
class Binode{
Binode prev;
Binode next;
String key;
int count;
Binode(){
prev = next = null;
}
Binode(String key){
prev = next = null;
this.key=key;
this.count =1;
}
}
class AllOne {
Binode head;
Binode tail;
Map<String,Binode> hash;
public AllOne() {
head=tail=null;
hash = new HashMap<String,Binode>();
}
public void swapKey(Binode a,Binode b){
String tmp = a.key;
a.key = b.key;
b.key = tmp;
}
public void swapCount(Binode a,Binode b){
int tmp = a.count;
a.count = b.count;
b.count = tmp;
}
public void del(Binode node){
if(node.prev !=null){
node.prev.next = node.next;
}else{
head = node.next;
}
if(node.next != null){
node.next.prev = node.prev;
}else{
tail = node.prev;
}
}
//将值向后平衡,大的往后放
public void balanceGoFront(Binode node){
while(node !=null &&node.next !=null){
if(node.count > node.next.count){
Binode nnext = node.next;
//交换key
swapKey(node,nnext);
//交换count
swapCount(node,nnext);
//更新hash
Binode tmp = hash.get(node.key);
hash.put(node.key,hash.get(nnext.key));
hash.put(nnext.key,tmp);
}
node = node.next;
}
}
//将值向后平衡,小的往前放
public void balanceGoBack(Binode node){
while(node !=null &&node.prev !=null){
if(node.count < node.prev.count){
Binode nprev = node.prev;
swapKey(node,nprev);
swapCount(node,nprev);
Binode tmp = hash.get(node.key);
hash.put(node.key,hash.get(nprev.key));
hash.put(nprev.key,tmp);
}
node = node.prev;
}
}
public void insertNode(Binode node){
if(head ==null){
head = tail = node;
}else{
head.prev = node;
node.next = head;
head = node;
}
}
public void inc(String key) {
Binode node;
if(!hash.containsKey(key)){
node = new Binode(key);
node.key = key;
node.count=1;
hash.put(key,node);
insertNode(node);
}else{
node = hash.get(key);
node.count++;
}
//计数新增以后 需要进行平衡重新排序,因为我们维护的是一个递增链表
balanceGoFront(node);
}
public void dec(String key) {
Binode node;
if(hash.containsKey(key)){
node = hash.get(key);
node.count--;
if(node.count == 0){
del(node);
}else{
balanceGoBack(node);
}
}else{
//do nothing
}
}
public String getMaxKey() {
if(tail ==null){
return "";
}
return tail.key;
}
public String getMinKey() {
if(head ==null){
return "";
}
return head.key;
}
}
/**
* 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();
*/