432. 全 O(1) 的資料結構
阿新 • • 發佈:2022-03-16
請你設計一個用於儲存字串計數的資料結構,並能夠返回計數最小和最大的字串。
實現 AllOne 類:
AllOne() 初始化資料結構的物件。 inc(String key) 字串 key 的計數增加 1 。如果資料結構中尚不存在 key ,那麼插入計數為 1 的 key 。 dec(String key) 字串 key 的計數減少 1 。如果 key 的計數在減少後為 0 ,那麼需要將這個 key 從資料結構中刪除。測試用例保證:在減少計數前,key 存在於資料結構中。 getMaxKey() 返回任意一個計數最大的字串。如果沒有元素存在,返回一個空字串 "" 。 getMinKey() 返回任意一個計數最小的字串。如果沒有元素存在,返回一個空字串 "" 。
來源:力扣(LeetCode) 連結:https://leetcode-cn.com/problems/all-oone-data-structure 著作權歸領釦網路所有。商業轉載請聯絡官方授權,非商業轉載請註明出處。
import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; class AllOne { private DoubleLinkedList doubleLinkedList; private Map<String, DoubleLinkedList.Node> nodeMap; public AllOne() { this.doubleLinkedList = new DoubleLinkedList(); this.nodeMap = new HashMap<>(); } public void inc(String key) { DoubleLinkedList.Node node = nodeMap.get(key); DoubleLinkedList.Node newNode; /** * 新的key */ if (node == null) { /** * 存在1的節點 */ if (doubleLinkedList.getHead().next.val == 1) { newNode = doubleLinkedList.getHead().next; newNode.keys.add(key); } else { /** * 不存在1的節點 */ newNode = new DoubleLinkedList.Node(1); newNode.keys.add(key); doubleLinkedList.insertAfter(doubleLinkedList.getHead(), newNode); } } else { /** * 老key */ /** * 從原節點刪除 */ node.keys.remove(key); if (node.val + 1 == node.next.val) { newNode = node.next; newNode.keys.add(key); nodeMap.put(key, newNode); } else { newNode = new DoubleLinkedList.Node(node.val + 1); newNode.keys.add(key); doubleLinkedList.insertAfter(node, newNode); nodeMap.put(key, newNode); } if (node.keys.size() == 0) { doubleLinkedList.remove(node); } } nodeMap.put(key, newNode); } public void dec(String key) { DoubleLinkedList.Node node = nodeMap.get(key); if (node != null) { node.keys.remove(key); if (node.val != 1) { if (node.prev == doubleLinkedList.getHead() || node.prev.val + 1 != node.val) { DoubleLinkedList.Node newNode = new DoubleLinkedList.Node(node.val - 1); newNode.keys.add(key); doubleLinkedList.insertAfter(node.prev, newNode); nodeMap.put(key, newNode); } else { DoubleLinkedList.Node newNode = node.prev; newNode.keys.add(key); nodeMap.put(key, newNode); } } else { nodeMap.remove(key); } if (node.keys.size() == 0) { doubleLinkedList.remove(node); } } } public String getMaxKey() { if (doubleLinkedList.getHead().next == doubleLinkedList.getTail()) { return ""; } return doubleLinkedList.getTail().prev.keys.iterator().next(); } public String getMinKey() { if (doubleLinkedList.getHead().next == doubleLinkedList.getTail()) { return ""; } return doubleLinkedList.getHead().next.keys.iterator().next(); } } class DoubleLinkedList { private Node head; private Node tail; public DoubleLinkedList() { this.head = new Node(0); this.tail = new Node(0); head.next = tail; tail.prev = head; } static class Node { int val; Node prev; Node next; Set<String> keys; public Node(int val) { this.val = val; this.keys = new HashSet<>(); } } public void remove(Node node) { Node prev = node.prev; Node next = node.next; prev.next = next; next.prev = prev; } public void insertAfter(Node node, Node inserted) { Node next = node.next; node.next = inserted; inserted.prev = node; inserted.next = next; next.prev = inserted; } public Node getHead() { return head; } public void setHead(Node head) { this.head = head; } public Node getTail() { return tail; } public void setTail(Node tail) { this.tail = tail; } } /** * 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(); */