Skip to content

Commit 747d590

Browse files
committed
+ problem 432
1 parent 24ad289 commit 747d590

File tree

5 files changed

+297
-0
lines changed

5 files changed

+297
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# 432. All O`one Data Structure
2+
Design a data structure to store the strings' count with the ability to return the strings with minimum and maximum counts.
3+
4+
Implement the `AllOne` class:
5+
6+
* `AllOne()` Initializes the object of the data structure.
7+
* `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`.
8+
* `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.
9+
* `getMaxKey()` Returns one of the keys with the maximal count. If no element exists, return an empty string `""`.
10+
* `getMinKey()` Returns one of the keys with the minimum count. If no element exists, return an empty string `""`.
11+
12+
**Note** that each function must run in `O(1)` average time complexity.
13+
14+
#### Example 1:
15+
<pre>
16+
<strong>Input:</strong>
17+
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
18+
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
19+
<strong>Output:</strong>
20+
[null, null, null, "hello", "hello", null, "hello", "leet"]
21+
<strong>Explanation:</strong>
22+
AllOne allOne = new AllOne();
23+
allOne.inc("hello");
24+
allOne.inc("hello");
25+
allOne.getMaxKey(); // return "hello"
26+
allOne.getMinKey(); // return "hello"
27+
allOne.inc("leet");
28+
allOne.getMaxKey(); // return "hello"
29+
allOne.getMinKey(); // return "leet"
30+
</pre>
31+
32+
#### Constraints:
33+
* `1 <= key.length <= 10`
34+
* `key` consists of lowercase English letters.
35+
* It is guaranteed that for each call to `dec`, `key` is existing in the data structure.
36+
* At most <code>5 * 10<sup>4</sup></code> calls will be made to `inc`, `dec`, `getMaxKey`, and `getMinKey`.
37+
38+
## Solutions (Python)
39+
40+
### 1. Solution
41+
```Python
42+
class AllOne:
43+
44+
def __init__(self):
45+
self.keys = []
46+
self.count = {}
47+
self.index = {}
48+
self.range = {}
49+
50+
def inc(self, key: str) -> None:
51+
if key not in self.count:
52+
self.keys.append(key)
53+
self.count[key] = 1
54+
self.index[key] = len(self.keys) - 1
55+
if 1 not in self.range:
56+
self.range[1] = [self.index[key], self.index[key]]
57+
self.range[1][1] = self.index[key]
58+
else:
59+
count0 = self.count[key]
60+
count1 = count0 + 1
61+
i = self.range[count0][0]
62+
j = self.index[key]
63+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
64+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
65+
self.count[key] += 1
66+
self.range[count0][0] += 1
67+
if self.range[count0][0] > self.range[count0][1]:
68+
self.range.pop(count0)
69+
if count1 not in self.range:
70+
self.range[count1] = [i, i]
71+
self.range[count1][1] = i
72+
73+
def dec(self, key: str) -> None:
74+
if self.count[key] == 1:
75+
self.index[self.keys[-1]] = self.index[key]
76+
self.keys[self.index[key]] = self.keys[-1]
77+
self.keys.pop()
78+
self.count.pop(key)
79+
self.index.pop(key)
80+
self.range[1][1] -= 1
81+
if self.range[1][0] > self.range[1][1]:
82+
self.range.pop(1)
83+
else:
84+
count0 = self.count[key]
85+
count1 = count0 - 1
86+
i = self.range[count0][1]
87+
j = self.index[key]
88+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
89+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
90+
self.count[key] -= 1
91+
self.range[count0][1] -= 1
92+
if self.range[count0][0] > self.range[count0][1]:
93+
self.range.pop(count0)
94+
if count1 not in self.range:
95+
self.range[count1] = [i, i]
96+
self.range[count1][0] = i
97+
98+
def getMaxKey(self) -> str:
99+
return self.keys[0] if self.keys != [] else ""
100+
101+
def getMinKey(self) -> str:
102+
return self.keys[-1] if self.keys != [] else ""
103+
104+
105+
# Your AllOne object will be instantiated and called as such:
106+
# obj = AllOne()
107+
# obj.inc(key)
108+
# obj.dec(key)
109+
# param_3 = obj.getMaxKey()
110+
# param_4 = obj.getMinKey()
111+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
# 432. 全 O(1) 的数据结构
2+
请你设计一个用于存储字符串计数的数据结构,并能够返回计数最小和最大的字符串。
3+
4+
实现 `AllOne` 类:
5+
6+
* `AllOne()` 初始化数据结构的对象。
7+
* `inc(String key)` 字符串 `key` 的计数增加 `1` 。如果数据结构中尚不存在 `key` ,那么插入计数为 `1``key`
8+
* `dec(String key)` 字符串 `key` 的计数减少 `1` 。如果 `key` 的计数在减少后为 `0` ,那么需要将这个 `key` 从数据结构中删除。测试用例保证:在减少计数前,`key` 存在于数据结构中。
9+
* `getMaxKey()` 返回任意一个计数最大的字符串。如果没有元素存在,返回一个空字符串 `""`
10+
* `getMinKey()` 返回任意一个计数最小的字符串。如果没有元素存在,返回一个空字符串 `""`
11+
12+
注意:每个函数都应当满足 `O(1)` 平均时间复杂度。
13+
14+
#### 示例 1:
15+
<pre>
16+
<strong>输入:</strong>
17+
["AllOne", "inc", "inc", "getMaxKey", "getMinKey", "inc", "getMaxKey", "getMinKey"]
18+
[[], ["hello"], ["hello"], [], [], ["leet"], [], []]
19+
<strong>输出:</strong>
20+
[null, null, null, "hello", "hello", null, "hello", "leet"]
21+
<strong>解释:</strong>
22+
AllOne allOne = new AllOne();
23+
allOne.inc("hello");
24+
allOne.inc("hello");
25+
allOne.getMaxKey(); // 返回 "hello"
26+
allOne.getMinKey(); // 返回 "hello"
27+
allOne.inc("leet");
28+
allOne.getMaxKey(); // 返回 "hello"
29+
allOne.getMinKey(); // 返回 "leet"
30+
</pre>
31+
32+
#### 提示:
33+
* `1 <= key.length <= 10`
34+
* `key` 由小写英文字母组成
35+
* 测试用例保证:在每次调用 `dec` 时,数据结构中总存在 `key`
36+
* 最多调用 `inc``dec``getMaxKey``getMinKey` 方法 <code>5 * 10<sup>4</sup></code> 次
37+
38+
## 题解 (Python)
39+
40+
### 1. 题解
41+
```Python
42+
class AllOne:
43+
44+
def __init__(self):
45+
self.keys = []
46+
self.count = {}
47+
self.index = {}
48+
self.range = {}
49+
50+
def inc(self, key: str) -> None:
51+
if key not in self.count:
52+
self.keys.append(key)
53+
self.count[key] = 1
54+
self.index[key] = len(self.keys) - 1
55+
if 1 not in self.range:
56+
self.range[1] = [self.index[key], self.index[key]]
57+
self.range[1][1] = self.index[key]
58+
else:
59+
count0 = self.count[key]
60+
count1 = count0 + 1
61+
i = self.range[count0][0]
62+
j = self.index[key]
63+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
64+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
65+
self.count[key] += 1
66+
self.range[count0][0] += 1
67+
if self.range[count0][0] > self.range[count0][1]:
68+
self.range.pop(count0)
69+
if count1 not in self.range:
70+
self.range[count1] = [i, i]
71+
self.range[count1][1] = i
72+
73+
def dec(self, key: str) -> None:
74+
if self.count[key] == 1:
75+
self.index[self.keys[-1]] = self.index[key]
76+
self.keys[self.index[key]] = self.keys[-1]
77+
self.keys.pop()
78+
self.count.pop(key)
79+
self.index.pop(key)
80+
self.range[1][1] -= 1
81+
if self.range[1][0] > self.range[1][1]:
82+
self.range.pop(1)
83+
else:
84+
count0 = self.count[key]
85+
count1 = count0 - 1
86+
i = self.range[count0][1]
87+
j = self.index[key]
88+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
89+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
90+
self.count[key] -= 1
91+
self.range[count0][1] -= 1
92+
if self.range[count0][0] > self.range[count0][1]:
93+
self.range.pop(count0)
94+
if count1 not in self.range:
95+
self.range[count1] = [i, i]
96+
self.range[count1][0] = i
97+
98+
def getMaxKey(self) -> str:
99+
return self.keys[0] if self.keys != [] else ""
100+
101+
def getMinKey(self) -> str:
102+
return self.keys[-1] if self.keys != [] else ""
103+
104+
105+
# Your AllOne object will be instantiated and called as such:
106+
# obj = AllOne()
107+
# obj.inc(key)
108+
# obj.dec(key)
109+
# param_3 = obj.getMaxKey()
110+
# param_4 = obj.getMinKey()
111+
```
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
class AllOne:
2+
3+
def __init__(self):
4+
self.keys = []
5+
self.count = {}
6+
self.index = {}
7+
self.range = {}
8+
9+
def inc(self, key: str) -> None:
10+
if key not in self.count:
11+
self.keys.append(key)
12+
self.count[key] = 1
13+
self.index[key] = len(self.keys) - 1
14+
if 1 not in self.range:
15+
self.range[1] = [self.index[key], self.index[key]]
16+
self.range[1][1] = self.index[key]
17+
else:
18+
count0 = self.count[key]
19+
count1 = count0 + 1
20+
i = self.range[count0][0]
21+
j = self.index[key]
22+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
23+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
24+
self.count[key] += 1
25+
self.range[count0][0] += 1
26+
if self.range[count0][0] > self.range[count0][1]:
27+
self.range.pop(count0)
28+
if count1 not in self.range:
29+
self.range[count1] = [i, i]
30+
self.range[count1][1] = i
31+
32+
def dec(self, key: str) -> None:
33+
if self.count[key] == 1:
34+
self.index[self.keys[-1]] = self.index[key]
35+
self.keys[self.index[key]] = self.keys[-1]
36+
self.keys.pop()
37+
self.count.pop(key)
38+
self.index.pop(key)
39+
self.range[1][1] -= 1
40+
if self.range[1][0] > self.range[1][1]:
41+
self.range.pop(1)
42+
else:
43+
count0 = self.count[key]
44+
count1 = count0 - 1
45+
i = self.range[count0][1]
46+
j = self.index[key]
47+
self.index[self.keys[i]], self.index[self.keys[j]] = j, i
48+
self.keys[i], self.keys[j] = self.keys[j], self.keys[i]
49+
self.count[key] -= 1
50+
self.range[count0][1] -= 1
51+
if self.range[count0][0] > self.range[count0][1]:
52+
self.range.pop(count0)
53+
if count1 not in self.range:
54+
self.range[count1] = [i, i]
55+
self.range[count1][0] = i
56+
57+
def getMaxKey(self) -> str:
58+
return self.keys[0] if self.keys != [] else ""
59+
60+
def getMinKey(self) -> str:
61+
return self.keys[-1] if self.keys != [] else ""
62+
63+
64+
# Your AllOne object will be instantiated and called as such:
65+
# obj = AllOne()
66+
# obj.inc(key)
67+
# obj.dec(key)
68+
# param_3 = obj.getMaxKey()
69+
# param_4 = obj.getMinKey()

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@
273273
[427][427l] |[Construct Quad Tree][427] |![py]
274274
[429][429l] |[N-ary Tree Level Order Traversal][429] |![py]&nbsp;&nbsp;![rb]
275275
[430][430l] |[Flatten a Multilevel Doubly Linked List][430] |![rb]
276+
[432][432l] |[All O`one Data Structure][432] |![py]
276277
[433][433l] |[Minimum Genetic Mutation][433] |![py]&nbsp;&nbsp;![rb]
277278
[434][434l] |[Number of Segments in a String][434] |![py]
278279
[435][435l] |[Non-overlapping Intervals][435] |![rs]
@@ -1697,6 +1698,7 @@
16971698
[427]:Problemset/0427-Construct%20Quad%20Tree/README.md#427-construct-quad-tree
16981699
[429]:Problemset/0429-N-ary%20Tree%20Level%20Order%20Traversal/README.md#429-n-ary-tree-level-order-traversal
16991700
[430]:Problemset/0430-Flatten%20a%20Multilevel%20Doubly%20Linked%20List/README.md#430-flatten-a-multilevel-doubly-linked-list
1701+
[432]:Problemset/0432-All%20O`one%20Data%20Structure/README.md#432-all-oone-data-structure
17001702
[433]:Problemset/0433-Minimum%20Genetic%20Mutation/README.md#433-minimum-genetic-mutation
17011703
[434]:Problemset/0434-Number%20of%20Segments%20in%20a%20String/README.md#434-number-of-segments-in-a-string
17021704
[435]:Problemset/0435-Non-overlapping%20Intervals/README.md#435-non-overlapping-intervals
@@ -3119,6 +3121,7 @@
31193121
[427l]:https://leetcode.com/problems/construct-quad-tree/
31203122
[429l]:https://leetcode.com/problems/n-ary-tree-level-order-traversal/
31213123
[430l]:https://leetcode.com/problems/flatten-a-multilevel-doubly-linked-list/
3124+
[432l]:https://leetcode.com/problems/all-oone-data-structure/
31223125
[433l]:https://leetcode.com/problems/minimum-genetic-mutation/
31233126
[434l]:https://leetcode.com/problems/number-of-segments-in-a-string/
31243127
[435l]:https://leetcode.com/problems/non-overlapping-intervals/

README_CN.md

+3
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,7 @@
273273
[427][427l] |[建立四叉树][427] |![py]
274274
[429][429l] |[N叉树的层序遍历][429] |![py]&nbsp;&nbsp;![rb]
275275
[430][430l] |[扁平化多级双向链表][430] |![rb]
276+
[432][432l] |[全 O(1) 的数据结构] |![py]
276277
[433][433l] |[最小基因变化][433] |![py]&nbsp;&nbsp;![rb]
277278
[434][434l] |[字符串中的单词数][434] |![py]
278279
[435][435l] |[无重叠区间][435] |![rs]
@@ -1697,6 +1698,7 @@
16971698
[427]:Problemset/0427-Construct%20Quad%20Tree/README_CN.md#427-建立四叉树
16981699
[429]:Problemset/0429-N-ary%20Tree%20Level%20Order%20Traversal/README_CN.md#429-n叉树的层序遍历
16991700
[430]:Problemset/0430-Flatten%20a%20Multilevel%20Doubly%20Linked%20List/README_CN.md#430-扁平化多级双向链表
1701+
[432]:Problemset/0432-All%20O`one%20Data%20Structure/README_CN.md#432-全-O1-的数据结构
17001702
[433]:Problemset/0433-Minimum%20Genetic%20Mutation/README_CN.md#433-最小基因变化
17011703
[434]:Problemset/0434-Number%20of%20Segments%20in%20a%20String/README_CN.md#434-字符串中的单词数
17021704
[435]:Problemset/0435-Non-overlapping%20Intervals/README_CN.md#435-无重叠区间
@@ -3119,6 +3121,7 @@
31193121
[427l]:https://leetcode.cn/problems/construct-quad-tree/
31203122
[429l]:https://leetcode.cn/problems/n-ary-tree-level-order-traversal/
31213123
[430l]:https://leetcode.cn/problems/flatten-a-multilevel-doubly-linked-list/
3124+
[432l]:https://leetcode.cn/problems/all-oone-data-structure/
31223125
[433l]:https://leetcode.cn/problems/minimum-genetic-mutation/
31233126
[434l]:https://leetcode.cn/problems/number-of-segments-in-a-string/
31243127
[435l]:https://leetcode.cn/problems/non-overlapping-intervals/

0 commit comments

Comments
 (0)