Hard
Design a stack-like data structure to push elements to the stack and pop the most frequent element from the stack.
Implement the FreqStack
class:
FreqStack()
constructs an empty frequency stack.void push(int val)
pushes an integer val
onto the top of the stack.int pop()
removes and returns the most frequent element in the stack.
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:
FreqStack freqStack = new FreqStack();
freqStack.push(5); // The stack is [5]
freqStack.push(7); // The stack is [5,7]
freqStack.push(5); // The stack is [5,7,5]
freqStack.push(7); // The stack is [5,7,5,7]
freqStack.push(4); // The stack is [5,7,5,7,4]
freqStack.push(5); // The stack is [5,7,5,7,4,5]
freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,5,7,4].
freqStack.pop(); // return 7, as 5 and 7 is the most frequent, but 7 is closest to the top. The stack becomes [5,7,5,4].
freqStack.pop(); // return 5, as 5 is the most frequent. The stack becomes [5,7,4].
freqStack.pop(); // return 4, as 4, 5 and 7 is the most frequent, but 4 is closest to the top. The stack becomes [5,7].
Constraints:
0 <= val <= 109
2 * 104
calls will be made to push
and pop
.pop
.class FreqStack {
private class Node {
var next: Node?
var `val` = 0
constructor(`val`: Int) {
this.`val` = `val`
next = null
}
constructor() {
next = null
}
}
private class DLL {
var head: Node = Node()
var size: Int = 0
fun addNode(x: Int) {
val node = Node(x)
node.next = head.next
head.next = node
size++
}
fun removeNode(): Node? {
val node = head.next
if (node != null) {
head.next = node.next
node.next = null
size--
}
return node
}
}
private var max = 0
private val freqMap: HashMap<Int, Int> = HashMap()
private val freqListMap: HashMap<Int, DLL> = HashMap()
fun push(`val`: Int) {
val count = freqMap.getOrDefault(`val`, 0) + 1
max = max.coerceAtLeast(count)
freqMap[`val`] = count
val dll = freqListMap.getOrDefault(count, DLL())
dll.addNode(`val`)
freqListMap[count] = dll
}
fun pop(): Int {
val dll = freqListMap[max]
val node = dll!!.removeNode()
freqMap[node!!.`val`] = max - 1
if (dll.size == 0) {
max--
}
return node.`val`
}
}
/*
* Your FreqStack object will be instantiated and called as such:
* var obj = FreqStack()
* obj.push(`val`)
* var param_2 = obj.pop()
*/