-
Notifications
You must be signed in to change notification settings - Fork 93
/
Copy pathMapSumPairs677.java
138 lines (114 loc) · 3.9 KB
/
MapSumPairs677.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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/**
* Implement a MapSum class with insert, and sum methods.
*
* For the method insert, you'll be given a pair of (string, integer). The
* string represents the key and the integer represents the value. If the key
* already existed, then the original key-value pair will be overridden to
* the new one.
*
* For the method sum, you'll be given a string representing the prefix, and
* you need to return the sum of all the pairs' value whose key starts with
* the prefix.
*
* Example 1:
* Input: insert("apple", 3), Output: Null
* Input: sum("ap"), Output: 3
* Input: insert("app", 2), Output: Null
* Input: sum("ap"), Output: 5
*
*/
public class MapSumPairs677 {
class MapSum {
private Trie trie = new Trie();
/** Initialize your data structure here. */
public MapSum() {
}
public void insert(String key, int val) {
trie.add(key, val);
}
public int sum(String prefix) {
return trie.getSum(prefix);
}
class Trie {
Trie[] children = new Trie[256];
Integer value;
Integer sum = 0;
public void add(String key, int val) {
add(key.toCharArray(), val, 0);
}
private Integer add(char[] chars, int val, int i) {
if (i == chars.length) {
int diff = (value == null) ? val : val - value;
value = val;
sum += diff;
return diff;
}
int nextI = (int) (chars[i] - 'a');
if (children[nextI] == null) {
children[nextI] = new Trie();
}
Integer pre = sum;
Integer diff = children[nextI].add(chars, val, i+1);
sum = pre + diff;
return diff;
}
public int getSum(String prefix) {
int s = getSum(prefix.toCharArray(), 0);
return s;
}
private int getSum(char[] chars, int i) {
if (i == chars.length) return sum;
if (children[chars[i] - 'a'] == null) return 0;
return children[chars[i] - 'a'].getSum(chars, i+1);
}
}
}
class MapSum2 {
private Map<String, Integer> map = new HashMap<>();
private Trie trie = new Trie();
/** Initialize your data structure here. */
public MapSum() {
}
public void insert(String key, int val) {
int now = map.getOrDefault(key, 0);
trie.add(key, val - now);
map.put(key, val);
}
public int sum(String prefix) {
return trie.getSum(prefix);
}
class Trie {
Trie[] children = new Trie[256];
Integer sum = 0;
public void add(String key, int diff) {
add(key.toCharArray(), diff, 0);
}
private void add(char[] chars, int diff, int i) {
if (i == chars.length) {
sum += diff;
return;
}
int nextI = (int) (chars[i] - 'a');
if (children[nextI] == null) {
children[nextI] = new Trie();
}
sum += diff;
children[nextI].add(chars, diff, i+1);
}
public int getSum(String prefix) {
return getSum(prefix.toCharArray(), 0);
}
private int getSum(char[] chars, int i) {
if (i == chars.length) return sum;
if (children[chars[i] - 'a'] == null) return 0;
return children[chars[i] - 'a'].getSum(chars, i+1);
}
}
}
/**
* Your MapSum object will be instantiated and called as such:
* MapSum obj = new MapSum();
* obj.insert(key,val);
* int param_2 = obj.sum(prefix);
*/
}