LeetCode/java/all-oone-data-structure.java

120 lines
2.2 KiB
Java
Raw Normal View History

import java.util.HashMap;
class AllOne {
private class Node {
int freq;
Node prev, next;
Set<String> keys = new HashSet<>();
Node(int freq) {
this.freq = freq;
}
Node(int freq, Node prev, Node next) {
this.freq = freq;
this.prev = prev;
prev.next = this;
this.next = next;
next.prev = this;
}
void link(Map<String, Node> map, String key) {
keys.add(key);
map.put(key, this);
}
void remove() {
var prev = this.prev;
var next = this.next;
prev.next = next;
next.prev = prev;
}
}
Node head, tail;
Map<String, Node> map = new HashMap<>();
public AllOne() {
head = new Node(0);
tail = new Node(0);
head.next = tail;
tail.prev = head;
}
public void inc(String key) {
if (!map.containsKey(key)) {
var first = head.next;
if (first != tail && first.freq <= 1) {
first.link(map, key);
return;
}
var newNode = new Node(1, head, first);
newNode.link(map, key);
return;
}
var node = map.get(key);
var freq = node.freq;
node.keys.remove(key);
var next = node.next;
if (next != tail && next.freq == freq + 1) {
next.link(map, key);
} else {
var newNode = new Node(freq + 1, node, next);
newNode.link(map, key);
}
if (node.keys.isEmpty()) {
node.remove();
}
}
public void dec(String key) {
if (!map.containsKey(key)) {
return;
}
var node = map.get(key);
var freq = node.freq;
node.keys.remove(key);
if (freq == 1) {
map.remove(key);
} else {
var prev = node.prev;
if (prev != head && prev.freq == freq - 1) {
prev.link(map, key);
} else {
var newNode = new Node(freq - 1, prev, node);
newNode.link(map, key);
}
}
if (node.keys.isEmpty()) {
node.remove();
}
}
public String getMaxKey() {
if (tail.prev == head) {
return "";
}
return tail.prev.keys.iterator().next();
}
public String getMinKey() {
if (head.next == tail) {
return "";
}
return head.next.keys.iterator().next();
}
}