Problem
Implement FreqStack
, a class which simulates the operation of a stack-like data structure.
FreqStack
has two functions:
push(int x)
, which pushes an integerx
onto the stack.pop()
, which removes and returns the most frequent element in the stack.- If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned.
Example 1:
1 | Input: |
Note :
- Calls to
FreqStack.push(int x)
will be such that0 <= x <= 10^9
. - It is guaranteed that
FreqStack.pop()
won’t be called if the stack has zero elements. - The total number of
FreqStack.push
calls will not exceed10000
in a single test case. - The total number of
FreqStack.pop
calls will not exceed10000
in a single test case. - The total number of
FreqStack.push
andFreqStack.pop
calls will not exceed150000
across all test cases.
Analysis
本题涉及到了数据结构中一个很重要的知识点–栈。栈的基本思想是FIFO,本题对FreqStack
重新定义,要求在FIFO的基础上,还要考虑元素出现的次数。解决这个问题的要点在于,我要知道当前出现最高的频度。除此之外,从出栈的角度来说,判定的条件的优先级是:出现频率>栈中先后顺序。我的解决方法是,在存储的时候就直接按照这个优先级,分级存储。
Solution
动态跟踪当前出现的最高频度,是当每一次插入新元素后,相应地检查的。因此我们需要一个map来记录每个元素出现的次数。
分级存储的实现也是充分利用map的特性,将key定义为频度(frequency),其value是一个栈。这就是说对于key = x
,只要元素A出现了x次,那么他就会插入到这个栈中。对于push操作
,我们可以通过先在记录出现频率的map中查找到某元素的出现次数count
,以此作为key,到分级存储的map中找到对应的栈,插入即可。而对于pop操作
,因为我们动态记录了出现的最大频度max
,因此只需要以max
作为key,在分级存储的map中找到相应位置的栈,pop
出栈顶元素即可。
特别注意,pop
后如果栈为空,就代表出现该频度的元素已经不存在了,这个时候需要将max
-1。
Code
1 | class FreqStack { |
运行时间:约172ms,超过65.12%的CPP代码。
Summary
这道题是对栈的一个创新,本质上还是对栈的使用。在统计数字或字母出现次数的时候,map是一个很好的工具,因为它维护的key是唯一的,且是自动排序的,因此以后遇到类似的题目应该首先考虑使用map,而不是vector。本题的分析就到这里,谢谢!