Skip to content

Commit 8c8d881

Browse files
authored
Added task 432.
1 parent e7f88c4 commit 8c8d881

File tree

3 files changed

+215
-0
lines changed

3 files changed

+215
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
package g0401_0500.s0432_all_oone_data_structure;
2+
3+
// #Hard #Hash_Table #Design #Linked_List #Doubly_Linked_List
4+
5+
import java.util.HashMap;
6+
import java.util.Map;
7+
8+
public class AllOne {
9+
private static class Node {
10+
String key;
11+
int val;
12+
Node prev;
13+
Node next;
14+
15+
Node(String key, int val) {
16+
this.key = key;
17+
this.val = val;
18+
}
19+
}
20+
21+
private static class DoubleLinkedList {
22+
Node head;
23+
Node tail;
24+
25+
DoubleLinkedList() {}
26+
27+
// Swap adjacent nodes till the node fits to its position
28+
Node fixOrder(Node node) {
29+
while (node.next != null && node.val > node.next.val) {
30+
swapAdjacentNodes(node, node.next);
31+
}
32+
while (node.prev != null && node.val < node.prev.val) {
33+
swapAdjacentNodes(node.prev, node);
34+
}
35+
return node;
36+
}
37+
38+
// Swap two adjacent nodes, where node1 -> node2
39+
void swapAdjacentNodes(Node node1, Node node2) {
40+
node1.next = node2.next;
41+
node2.prev = node1.prev;
42+
if (node1.next != null) {
43+
node1.next.prev = node1;
44+
}
45+
if (node2.prev != null) {
46+
node2.prev.next = node2;
47+
}
48+
node1.prev = node2;
49+
node2.next = node1;
50+
// node0 -> node2 -> node1 -> node3
51+
if (node1 == head) {
52+
head = node2;
53+
}
54+
if (node2 == tail) {
55+
tail = node1;
56+
}
57+
}
58+
// New node has counter 1 and should be at the head of the list
59+
Node add(Node node) {
60+
node.next = head;
61+
if (head != null) {
62+
head.prev = node;
63+
}
64+
head = node;
65+
// is it is the first node
66+
if (tail == null) {
67+
tail = head;
68+
}
69+
return node;
70+
}
71+
72+
void remove(Node node) {
73+
if (node.prev != null) {
74+
node.prev.next = node.next;
75+
} else {
76+
head = node.next;
77+
}
78+
if (node.next != null) {
79+
node.next.prev = node.prev;
80+
} else {
81+
tail = node.prev;
82+
}
83+
}
84+
}
85+
86+
private DoubleLinkedList dll = new DoubleLinkedList();
87+
private Map<String, Node> counter = new HashMap<>();
88+
89+
/* Initialize your data structure here. */
90+
public AllOne() {
91+
// empty
92+
}
93+
94+
/* Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
95+
public void inc(String key) {
96+
Node node = counter.get(key);
97+
if (node == null) {
98+
node = new Node(key, 1);
99+
counter.put(key, node);
100+
// add first
101+
dll.add(node);
102+
} else {
103+
node.val++;
104+
// after increment/decrement node may have incorrect position.
105+
dll.fixOrder(node);
106+
}
107+
}
108+
109+
/* Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
110+
public void dec(String key) {
111+
Node node = counter.get(key);
112+
if (node == null) {
113+
return;
114+
}
115+
node.val--;
116+
if (node.val == 0) {
117+
counter.remove(key);
118+
// completely remove node from list
119+
dll.remove(node);
120+
} else {
121+
// after increment/decrement node may have incorrect position.
122+
dll.fixOrder(node);
123+
}
124+
}
125+
126+
/* Returns one of the keys with maximal value. */
127+
public String getMaxKey() {
128+
if (dll.tail == null) {
129+
return "";
130+
}
131+
return dll.tail.key;
132+
}
133+
134+
/* Returns one of the keys with Minimal value. */
135+
public String getMinKey() {
136+
if (dll.head == null) {
137+
return "";
138+
}
139+
return dll.head.key;
140+
}
141+
}
142+
143+
/*
144+
* Your AllOne object will be instantiated and called as such:
145+
* AllOne obj = new AllOne();
146+
* obj.inc(key);
147+
* obj.dec(key);
148+
* String param_3 = obj.getMaxKey();
149+
* String param_4 = obj.getMinKey();
150+
*/
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
432\. All O\`one Data Structure
2+
3+
Hard
4+
5+
Design a data structure to store the strings' count with the ability to return the strings with minimum and maximum counts.
6+
7+
Implement the `AllOne` class:
8+
9+
* `AllOne()` Initializes the object of the data structure.
10+
* `inc(String key)` Increments the count of the string `key` by `1`. If `key` does not exist in the data structure, insert it with count `1`.
11+
* `dec(String key)` Decrements the count of the string `key` by `1`. If the count of `key` is `0` after the decrement, remove it from the data structure. It is guaranteed that `key` exists in the data structure before the decrement.
12+
* `getMaxKey()` Returns one of the keys with the maximal count. If no element exists, return an empty string `""`.
13+
* `getMinKey()` Returns one of the keys with the minimum count. If no element exists, return an empty string `""`.
14+
15+
**Example 1:**
16+
17+
**Input**
18+
19+
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
20+
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
21+
22+
**Output:** [null, null, null, "hello", "hello", null, "hello", "leet"]
23+
24+
**Explanation:**
25+
26+
AllOne allOne = new AllOne();
27+
allOne.inc("hello");
28+
allOne.inc("hello");
29+
allOne.getMaxKey(); // return "hello"
30+
allOne.getMinKey(); // return "hello"
31+
allOne.inc("leet");
32+
allOne.getMaxKey(); // return "hello"
33+
allOne.getMinKey(); // return "leet"
34+
35+
**Constraints:**
36+
37+
* `1 <= key.length <= 10`
38+
* `key` consists of lowercase English letters.
39+
* It is guaranteed that for each call to `dec`, `key` is existing in the data structure.
40+
* At most <code>5 * 10<sup>4</sup></code> calls will be made to `inc`, `dec`, `getMaxKey`, and `getMinKey`.
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package g0401_0500.s0432_all_oone_data_structure;
2+
3+
import static org.hamcrest.CoreMatchers.equalTo;
4+
import static org.hamcrest.MatcherAssert.assertThat;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
class AllOneTest {
9+
@Test
10+
void allOne() {
11+
AllOne allOne = new AllOne();
12+
allOne.inc("hello");
13+
allOne.inc("hello");
14+
// return "hello"
15+
assertThat(allOne.getMaxKey(), equalTo("hello"));
16+
// return "hello"
17+
assertThat(allOne.getMinKey(), equalTo("hello"));
18+
allOne.inc("leet");
19+
// return "hello"
20+
assertThat(allOne.getMaxKey(), equalTo("hello"));
21+
// return "leet"
22+
assertThat(allOne.getMinKey(), equalTo("leet"));
23+
allOne.dec("leet");
24+
}
25+
}

0 commit comments

Comments
 (0)