-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathAll O1 Data Structure.java
120 lines (105 loc) · 3.36 KB
/
All O1 Data Structure.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class AllOne {
//** A class of all keys with same value */
private class Bucket {
public int value;
public Set<String> set;
Bucket prev, next;
public Bucket(int v) {
this.value = v;
set = new HashSet<>();
}
}
private Bucket head, tail;
private Map<String, Integer> vals;
private Map<Integer, Bucket> bucs;
/** Initialize your data structure here. */
public AllOne() {
head = new Bucket(Integer.MIN_VALUE);
tail = new Bucket(Integer.MAX_VALUE);
head.next = tail;
tail.prev = head;
// Head and tail not in bucs map
vals = new HashMap<>();
bucs = new HashMap<>();
}
/** Inserts a new key <Key> with value 1. Or increments an existing key by 1. */
public void inc(String key) {
if(vals.containsKey(key)) {
updateKey(key, 1);
}
else {
vals.put(key, 1);
if(head.next.value != 1) {
insertBucketAfter(new Bucket(1), head);
}
bucs.put(1, head.next);
insertKeyToBucket(key, bucs.get(1));
}
}
/** Decrements an existing key by 1. If Key's value is 1, remove it from the data structure. */
public void dec(String key) {
if(vals.containsKey(key)) {
if(vals.get(key) == 1) {
vals.remove(key);
deleteKeyFromBucket(key, bucs.get(1));
}
else updateKey(key, -1);
}
}
/** Returns one of the keys with maximal value. */
public String getMaxKey() {
return tail.prev == head? "": tail.prev.set.iterator().next();
}
/** Returns one of the keys with Minimal value. */
public String getMinKey() {
return head.next == tail? "": head.next.set.iterator().next();
}
// Helpers
private void updateKey(String key, int offset) {
// Offset is either 1 or -1
int v = vals.get(key);
vals.put(key, v+offset);
Bucket cur = bucs.get(v);
Bucket next;
if(bucs.containsKey(v+offset)) {
next = bucs.get(v+offset);
}
else {
next = new Bucket(v+offset);
insertBucketAfter(next, offset == 1? cur: cur.prev);
bucs.put(next.value, next);
}
insertKeyToBucket(key, next);
deleteKeyFromBucket(key, cur);
}
private void insertBucketAfter(Bucket b, Bucket prev) {
b.prev = prev;
b.next = prev.next;
prev.next.prev = b;
prev.next = b;
}
private void removeBucket(Bucket b) {
b.prev.next = b.next;
b.next.prev = b.prev;
b.prev = null;
b.next = null;
}
private void insertKeyToBucket(String key, Bucket b) {
b.set.add(key);
}
private void deleteKeyFromBucket(String key, Bucket b) {
b.set.remove(key);
if(b.set.size() == 0) {
removeBucket(b);
bucs.remove(b.value);
}
}
}
/**
* 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();
*/