难度:困难
请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。
实现
AllOne
类:
AllOne()
初始化数据结构的对象。inc(String key)
字符串key
的计数增加1
。如果数据结构中尚不存在key
,那么插入计数为1
的key
。dec(String key)
字符串key
的计数减少1
。如果key
的计数在减少后为0
,那么需要将这个key
从数据结构中删除。测试用例保证:在减少计数前,key
存在于数据结构中。getMaxKey()
返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串""
。getMinKey()
返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串""
。示例:
输入 ["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"提示:
1 <= key.length <= 10
key
由小写英文字母组成- 测试用例保证:在每次调用
dec
时,数据结构中总存在key
- 最多调用
inc
、dec
、getMaxKey
和getMinKey
方法5 *
次
class AllOne {
private Map<String, Node> nodes;
private Node root;
public AllOne() {
root = new Node();
root.prev = root;
root.next = root;
nodes = new HashMap<>();
}
public void inc(String key) {
if (nodes.containsKey(key)) {
Node curr = nodes.get(key);
Node next = curr.next;
if (next == root || next.count > curr.count + 1) {
nodes.put(key, curr.insert(new Node(key, curr.count + 1)));
} else {
next.keys.add(key);
nodes.put(key, next);
}
curr.keys.remove(key);
if (curr.keys.isEmpty()) {
curr.remove();
}
} else {
if (root.next == root || root.next.count > 1) {
nodes.put(key, root.insert(new Node(key, 1)));
} else {
root.next.keys.add(key);
nodes.put(key, root.next);
}
}
}
public void dec(String key) {
Node cur = nodes.get(key);
// key 仅出现一次,将其移出 nodes
if (cur.count == 1) {
nodes.remove(key);
} else {
Node pre = cur.prev;
if (pre == root || pre.count < cur.count - 1) {
nodes.put(key, cur.prev.insert(new Node(key, cur.count - 1)));
} else {
pre.keys.add(key);
nodes.put(key, pre);
}
}
cur.keys.remove(key);
if (cur.keys.isEmpty()) {
cur.remove();
}
}
public String getMaxKey() {
return root.prev != null ? root.prev.keys.iterator().next() : "";
}
public String getMinKey() {
return root.next != null ? root.next.keys.iterator().next() : "";
}
}
class Node {
Node prev;
Node next;
/**
* 出现次数相同的key
*/
Set<String> keys;
/**
* 出现的次数
*/
int count;
public Node() {
this("", 0);
}
public Node(String key, int count) {
this.count = count;
keys = new HashSet<>();
keys.add(key);
}
/**
* 在this后面插入node
*
* @param node
* @return
*/
public Node insert(Node node) {
node.prev = this;
node.next = this.next;
node.prev.next = node;
node.next.prev = node;
return node;
}
public void remove() {
this.next.prev = this.prev;
this.prev.next = this.next;
}
}