#432
All O`one Data Structure
HardHash TableLinked ListDesignDoubly-Linked ListHash MapDoubly Linked List
Approaches
Brute ForceOptimal
Complexity Comparison
| Brute Force | Optimal Solution★ | |
|---|---|---|
| Time | O(n²) | O(1) |
| Space | O(n) | O(n) |
💡
Intuition
Time O(1)Space O(n)
This approach uses a combination of a hash map and a doubly linked list to maintain the counts efficiently. The linked list allows for quick access to the minimum and maximum counts while the hash map keeps track of the keys and their corresponding nodes in the list.
⚙️
Algorithm
3 steps- 1Step 1: Create a doubly linked list to maintain nodes representing counts.
- 2Step 2: Use a hash map to map each string to its count and the corresponding node in the linked list.
- 3Step 3: For increment and decrement operations, update the count and adjust the linked list accordingly to maintain order.
solution.py54 lines
1class Node:
2 def __init__(self, count):
3 self.count = count
4 self.keys = set()
5 self.prev = None
6 self.next = None
7
8class AllOne:
9 def __init__(self):
10 self.key_count = {}
11 self.head = Node(float('-inf'))
12 self.tail = Node(float('inf'))
13 self.head.next = self.tail
14 self.tail.prev = self.head
15
16 def _add_node(self, new_node, prev_node):
17 new_node.prev = prev_node
18 new_node.next = prev_node.next
19 prev_node.next.prev = new_node
20 prev_node.next = new_node
21
22 def _remove_node(self, node):
23 node.prev.next = node.next
24 node.next.prev = node.prev
25
26 def inc(self, key: str) -> None:
27 count = self.key_count.get(key, 0)
28 self.key_count[key] = count + 1
29 if count:
30 self._remove_node(self.key_count[key])
31 new_count = count + 1
32 if new_count not in self.key_count:
33 new_node = Node(new_count)
34 self._add_node(new_node, self.head)
35 self.head.next.keys.add(key)
36
37 def dec(self, key: str) -> None:
38 count = self.key_count[key]
39 self._remove_node(self.key_count[key])
40 if count == 1:
41 del self.key_count[key]
42 else:
43 self.key_count[key] = count - 1
44 new_count = count - 1
45 if new_count not in self.key_count:
46 new_node = Node(new_count)
47 self._add_node(new_node, self.head)
48 self.head.next.keys.add(key)
49
50 def getMaxKey(self) -> str:
51 return "" if self.head.next == self.tail else next(iter(self.head.next.keys))
52
53 def getMinKey(self) -> str:
54 return "" if self.tail.prev == self.head else next(iter(self.tail.prev.keys))ℹ
Complexity note: The time complexity is O(1) for all operations because we use a hash map for key counts and a linked list for maintaining order, allowing for constant time access to max and min keys.
- 1Using a linked list allows for efficient insertions and deletions while maintaining order.
- 2A hash map provides O(1) access to the count of each key, which is crucial for performance.
Solutions and explanations are original Tejav content. Problem titles © LeetCode — use the LeetCode button above for the full problem statement.