LeetCode 895. 最大频率栈 题解,熟练掌握数据结构、集合的解法。
题目
1895. 最大频率栈
https://leetcode.cn/problems/maximum-frequency-stack/
设计一个类似堆栈的数据结构,将元素推入堆栈,并从堆栈中弹出出现频率最高的元素。
实现 FreqStack 类:
- FreqStack() 构造一个空的堆栈。
- void push(int val) 将一个整数 val 压入栈顶。
- int pop() 删除并返回堆栈中出现频率最高的元素。
- 如果出现频率最高的元素不只一个,则移除并返回最接近栈顶的元素。
思路
这道题与 LeetCode 146. LRU 缓存 双向链表题解 类似。
都是在基础数据结构之上,增加了应用层功能。
LRU
中,我们使用了链表来维护一个队列:
- 数据写入时:
- 如果数据已存在,则删除队列已有元素,将元素插入到队头;
- 如果数据不存在,则直接将元素插入到队头;
- 数据读取时:
- 数据不存在,不做任何操作;
- 数据存在:
- 返回找到的数据(可能是
KV
结构); - 删除数据原位置,将数据插入到队头;
- 返回找到的数据(可能是
为了提高效率,我们使用了双向链表+map
,方便定位数据、原地删除数据、头尾增删数据。言下之意,我们可以使用粗暴的解决方式,只是效率不高。
LRU
中,在原始集合基础上,对数据访问(读、写)增加了前置元素到队头的逻辑。
而本题所求最大频率栈,则是在栈的基础上,对对数据访问(读、写)增加了更新频率的逻辑。
维护频率值+map
思路
按照上述分析,我们需要维护、更新:
- 频率
- 集合元素最大频率
- 每个元素对应频率
- 栈
- 负责读写
复杂度分析
时间
push
- 操作均为
map
/stack
O(1)
复杂度
- 操作均为
pop
- 操作均为
map
/stack
O(1)
复杂度
- 操作均为
空间
使用了额外的map
stack
,空间占用O(n)
。
代码
|
|