Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 9159b3b

Browse files
✨feat: add 895
1 parent aa26a08 commit 9159b3b

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

‎Index/哈希表.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
| [884. 两句话中的不常见单词](https://leetcode-cn.com/problems/uncommon-words-from-two-sentences/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/uncommon-words-from-two-sentences/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-wwam/) | 简单 | 🤩🤩🤩🤩🤩 |
5959
| [888. 公平的糖果棒交换](https://leetcode-cn.com/problems/fair-candy-swap/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/fair-candy-swap/solution/gong-shui-san-xie-yi-ti-shuang-jie-po-su-uant/) | 简单 | 🤩🤩 |
6060
| [890. 查找和替换模式](https://leetcode.cn/problems/find-and-replace-pattern/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-and-replace-pattern/solution/by-ac_oier-s4cw/) | 中等 | 🤩🤩🤩🤩 |
61+
| [895. 最大频率栈](https://leetcode.cn/problems/maximum-frequency-stack/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-frequency-stack/solution/by-ac_oier-tquk/) | 困难 | 🤩🤩🤩🤩🤩 |
6162
| [930. 和相同的二元子数组](https://leetcode-cn.com/problems/binary-subarrays-with-sum/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/binary-subarrays-with-sum/solution/gong-shui-san-xie-yi-ti-shuang-jie-qian-hfoc0/) | 中等 | 🤩🤩🤩 |
6263
| [954. 二倍数对数组](https://leetcode-cn.com/problems/array-of-doubled-pairs/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/array-of-doubled-pairs/solution/by-ac_oier-d1z7/) | 中等 | 🤩🤩🤩 |
6364
| [961. 在长度 2N 的数组中找出重复 N 次的元素](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/) | [LeetCode 题解链接](https://leetcode.cn/problems/n-repeated-element-in-size-2n-array/solution/by-ac_oier-bslq/) | 简单 | 🤩🤩🤩🤩 |

‎Index/模拟.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
| [883. 三维形体投影面积](https://leetcode-cn.com/problems/projection-area-of-3d-shapes/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/projection-area-of-3d-shapes/solution/by-ac_oier-r6hj/) | 简单 | 🤩🤩🤩🤩 |
127127
| [884. 两句话中的不常见单词](https://leetcode-cn.com/problems/uncommon-words-from-two-sentences/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/uncommon-words-from-two-sentences/solution/gong-shui-san-xie-shu-ju-jie-gou-mo-ni-t-wwam/) | 简单 | 🤩🤩🤩🤩 |
128128
| [890. 查找和替换模式](https://leetcode.cn/problems/find-and-replace-pattern/) | [LeetCode 题解链接](https://leetcode.cn/problems/find-and-replace-pattern/solution/by-ac_oier-s4cw/) | 中等 | 🤩🤩🤩🤩 |
129+
| [895. 最大频率栈](https://leetcode.cn/problems/maximum-frequency-stack/) | [LeetCode 题解链接](https://leetcode.cn/problems/maximum-frequency-stack/solution/by-ac_oier-tquk/) | 困难 | 🤩🤩🤩🤩🤩 |
129130
| [896. 单调数列](https://leetcode-cn.com/problems/monotonic-array/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/monotonic-array/solution/wei-shi-yao-yi-ci-bian-li-yao-bi-liang-c-uglp/) | 简单 | 🤩🤩🤩🤩 |
130131
| [905. 按奇偶排序数组](https://leetcode-cn.com/problems/sort-array-by-parity/) | [LeetCode 题解链接](https://leetcode-cn.com/problems/sort-array-by-parity/solution/by-ac_oier-nuz7/) | 简单 | 🤩🤩🤩 |
131132
| [915. 分割数组](https://leetcode.cn/problems/partition-array-into-disjoint-intervals/) | [LeetCode 题解链接](https://leetcode.cn/problems/partition-array-into-disjoint-intervals/solution/by-ac_oier-yyen/) | 中等 | 🤩🤩🤩🤩 |
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
### 题目描述
2+
3+
这是 LeetCode 上的 **[895. 最大频率栈](https://leetcode.cn/problems/maximum-frequency-stack/solution/by-ac_oier-tquk/)** ,难度为 **困难**
4+
5+
Tag : 「哈希表」、「模拟」
6+
7+
8+
9+
设计一个类似堆栈的数据结构,将元素推入堆栈,并从堆栈中弹出出现频率最高的元素。
10+
11+
实现 `FreqStack` 类:
12+
* `FreqStack()` 构造一个空的堆栈。
13+
* `void push(int val)` 将一个整数 `val` 压入栈顶。
14+
* `int pop()` 删除并返回堆栈中出现频率最高的元素。
15+
16+
如果出现频率最高的元素不只一个,则移除并返回最接近栈顶的元素。
17+
18+
示例 1:
19+
```
20+
输入:
21+
["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
22+
[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
23+
24+
输出:[null,null,null,null,null,null,null,5,7,5,4]
25+
26+
解释:
27+
FreqStack = new FreqStack();
28+
freqStack.push (5);//堆栈为 [5]
29+
freqStack.push (7);//堆栈是 [5,7]
30+
freqStack.push (5);//堆栈是 [5,7,5]
31+
freqStack.push (7);//堆栈是 [5,7,5,7]
32+
freqStack.push (4);//堆栈是 [5,7,5,7,4]
33+
freqStack.push (5);//堆栈是 [5,7,5,7,4,5]
34+
freqStack.pop ();//返回 5 ,因为 5 出现频率最高。堆栈变成 [5,7,5,7,4]。
35+
freqStack.pop ();//返回 7 ,因为 5 和 7 出现频率最高,但7最接近顶部。堆栈变成 [5,7,5,4]。
36+
freqStack.pop ();//返回 5 ,因为 5 出现频率最高。堆栈变成 [5,7,4]。
37+
freqStack.pop ();//返回 4 ,因为 4, 5 和 7 出现频率最高,但 4 是最接近顶部的。堆栈变成 [5,7]。
38+
```
39+
40+
提示:
41+
* 0ドル <= val <= 10^9$
42+
* `push``pop` 的操作数不大于 2ドル \times 10^4$
43+
* 输入保证在调用 `pop` 之前堆栈中至少有一个元素
44+
45+
---
46+
47+
### 哈希表
48+
49+
这是一道很纯的哈希表题儿。
50+
51+
首先,我们容易想到建立 **第一个哈希表 `cnts` 用于记录某个数值的出现次数,`cnts[val] = c` 含义为数值 `val` 当前在栈中的出现次数为 `c`。我们称该哈希表为「计数哈希表」**
52+
53+
再结合每次 `pop` 需要返回「频率最大的元素,若有多个则返回最考虑栈顶的一个」的要求,我们还可以 **建立第二个哈希 `map`,该哈希表以「出现次数 `c`」为键,以「出现次数均为 `c` 的元素序列」为值,`map[c] = A = [...]` 含义为出现次数为 `c` 的序列为 `A`,并且序列 `A` 中的结尾元素为出现次数为 `c` 的所有元素中最靠近栈顶的元素。我们称该哈希表为「分桶哈希表」**
54+
55+
最后再额外使用一个变量 `max` 记录当前最大出现频数,不难发现,`max` 必然是以步长 $\pm 1$ 进行变化(当出现次数为 `max` 的元素被 `pop` 掉了一个后,必然剩下 `max - 1` 个),因此当我们在某次 `pop` 操作后发现出现次数为 `max` 的集合为空时,对 `max` 进行自减操作即可。
56+
57+
将题目给的样例作为 🌰 ,大家可以看看 `cnts``map``max` 三者如何变化,以及 `pop` 的更新逻辑:
58+
59+
![image.png](https://pic.leetcode.cn/1669771856-XhpLSw-image.png)
60+
61+
Java 代码:
62+
```Java
63+
class FreqStack {
64+
Map<Integer, List<Integer>> map = new HashMap<>();
65+
Map<Integer, Integer> cnts = new HashMap<>();
66+
int max;
67+
public void push(int val) {
68+
cnts.put(val, cnts.getOrDefault(val, 0) + 1);
69+
int c = cnts.get(val);
70+
List<Integer> list = map.getOrDefault(c, new ArrayList<>());
71+
list.add(val);
72+
map.put(c, list);
73+
max = Math.max(max, c);
74+
}
75+
public int pop() {
76+
List<Integer> list = map.get(max);
77+
int ans = list.remove(list.size() - 1);
78+
cnts.put(ans, cnts.get(ans) - 1);
79+
if (list.size() == 0) max--;
80+
return ans;
81+
}
82+
}
83+
```
84+
TypeScript 代码:
85+
```TypeScript
86+
class FreqStack {
87+
map: Map<number, Array<number>> = new Map<number, Array<number>>()
88+
cnst: Map<number, number> = new Map<number, number>()
89+
max: number = 0
90+
push(val: number): void {
91+
if (!this.cnst.has(val)) this.cnst.set(val, 0)
92+
this.cnst.set(val, this.cnst.get(val) + 1)
93+
const c = this.cnst.get(val)
94+
if (!this.map.has(c)) this.map.set(c, new Array<number>())
95+
this.map.get(c).push(val)
96+
this.max = Math.max(this.max, c)
97+
}
98+
pop(): number {
99+
const ans = this.map.get(this.max).pop()
100+
if (this.map.get(this.max).length == 0) this.max--
101+
this.cnst.set(ans, this.cnst.get(ans) - 1)
102+
return ans
103+
}
104+
}
105+
```
106+
Python 代码:
107+
```Python
108+
class FreqStack:
109+
def __init__(self):
110+
self.cnts = defaultdict(int)
111+
self.map = defaultdict(list)
112+
self.mv = 0
113+
114+
def push(self, val: int) -> None:
115+
self.cnts[val] += 1
116+
c = self.cnts[val]
117+
self.map[c].append(val)
118+
self.mv = max(self.mv, c)
119+
120+
def pop(self) -> int:
121+
ans = self.map[self.mv].pop()
122+
self.cnts[ans] -= 1
123+
self.mv -= 0 if self.map[self.mv] else 1
124+
return ans
125+
```
126+
* 时间复杂度:所有操作均为 $O(1)$
127+
* 空间复杂度:所有入栈的节点最多会被存储两次,一次在计数哈希表中,一次在分桶哈希表中,复杂度为 $O(n)$
128+
129+
---
130+
131+
### 最后
132+
133+
这是我们「刷穿 LeetCode」系列文章的第 `No.895` 篇,系列开始于 2021年01月01日,截止于起始日 LeetCode 上共有 1916 道题目,部分是有锁题,我们将先把所有不带锁的题目刷完。
134+
135+
在这个系列文章里面,除了讲解解题思路以外,还会尽可能给出最为简洁的代码。如果涉及通解还会相应的代码模板。
136+
137+
为了方便各位同学能够电脑上进行调试和提交代码,我建立了相关的仓库:https://github.com/SharingSource/LogicStack-LeetCode
138+
139+
在仓库地址里,你可以看到系列文章的题解链接、系列文章的相应代码、LeetCode 原题链接和其他优选题解。
140+

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /