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:
Input:
["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
Output: [null,null,null,null,null,null,null,5,7,5,4]
Explanation:
After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then:
pop() -> returns 5, as 5 is the most frequent.
The stack becomes [5,7,5,7,4].
pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.
The stack becomes [5,7,5,4].
pop() -> returns 5.
The stack becomes [5,7,4].
pop() -> returns 4.
The stack becomes [5,7].
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.
一开始想到的就是优先队列+Map,优先队列放(-count, -index, key),但是有点卡住,就是如果key现在count是val,再来一个key,count变成val+1,那岂不是要把之前对应的tuple从优先队列里面删除?但是我不知道index啊,那就还得额外用一个Map来缓存一下index??想来想去还是太复杂了
然后发现,其实完全不用删除啊!因为你删除的话,后面pop又得加回来啊,还不如就全部放在优先队列里面呢!
因为本身stack里面那个数还是在的,不能pop
也就是用(count,加入的idx)来唯一表示一个数呗,加入的idx可能并不能代表在stack中的index,但是顺序是对的就OK
class FreqStack:
def __init__(self):
self.heap = []
self.m = collections.defaultdict(int)
self.counter = 0
def push(self, x):
self.m[x]+=1
heapq.heappush(self.heap,(-self.m[x], -self.counter, x))
self.counter+=1
def pop(self):
toBeRemoved = heapq.heappop(self.heap)
self.m[toBeRemoved[2]]-=1
return toBeRemoved[2]
另外一个解法也是:key的count为val,那就把1..val累加的过中所有的都加到Map里面
def __init__(self):
self.freq = collections.Counter()
self.m = collections.defaultdict(list)
self.maxf = 0
def push(self, x):
freq, m = self.freq, self.m
freq[x] += 1
self.maxf = max(self.maxf, freq[x])
m[freq[x]].append(x)
def pop(self):
freq, m, maxf = self.freq, self.m, self.maxf
x = m[maxf].pop()
if not m[maxf]: self.maxf = maxf - 1
freq[x] -= 1
return x