题目
请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。
实现 AllOne 类:
AllOne() 初始化数据结构的对象。
inc(String key) 字符串 key 的计数增加 1 。如果数据结构中尚不存在 key ,那么插入计数为 1 的 key 。
dec(String key) 字符串 key 的计数减少 1 。如果 key 的计数在减少后为 0 ,那么需要将这个 key 从数据结构中删除。测试用例保证:在减少计数前,key 存在于数据结构中。
getMaxKey() 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 “” 。
getMinKey() 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 “” 。
注意:每个函数都应当满足 O(1) 平均时间复杂度。
示例:
输入
[“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”
解
class AllOne {
class Node {
int val;
Set<String> keys;
Node pre;
Node next;
public Node(int val) {
this.val = val;
keys = new HashSet<>();
}
}
Map<String, Node> map;
Node head;
Node tail;
public AllOne() {
map = new HashMap<>();
head = new Node(-1);
tail = new Node(-1);
head.next = tail;
tail.pre = head;
}
public void clear(Node node) {
if (node.keys.size() == 0) {
node.pre.next = node.next;
node.next.pre = node.pre;
}
}
public void inc(String key) {
Node newNode = null;
if (map.containsKey(key)) {
Node node = map.get(key);
if (node.next.val == node.val + 1) {
newNode = node.next;
} else {
newNode = new Node(node.val + 1);
Node temp = node.next;
node.next = newNode;
newNode.pre = node;
newNode.next = temp;
temp.pre = newNode;
}
node.keys.remove(key);
clear(node);
map.remove(key);
newNode.keys.add(key);
map.put(key, newNode);
} else {
if (head.next.val == 1) {
newNode = head.next;
} else {
newNode = new Node(1);
Node temp = head.next;
head.next = newNode;
newNode.pre = head;
newNode.next = temp;
temp.pre = newNode;
}
newNode.keys.add(key);
map.put(key, newNode);
}
}
public void dec(String key) {
Node node = map.get(key);
node.keys.remove(key);
map.remove(key);
Node newNode = null;
if (node.val == 1) {
} else if (node.pre.val == node.val - 1) {
newNode = node.pre;
newNode.keys.add(key);
map.put(key, newNode);
} else {
newNode = new Node(node.val - 1);
Node temp = node.pre;
node.pre = newNode;
newNode.next = node;
newNode.pre = temp;
temp.next = newNode;
newNode.keys.add(key);
map.put(key, newNode);
}
clear(node);
}
public String getMaxKey() {
for (String key : tail.pre.keys) {
return key;
}
return "";
}
public String getMinKey() {
for (String key : head.next.keys) {
return key;
}
return "";
}
}