895. Maximum Frequency Stack
Problem
Tags: Hash Table
, Stack
, Design
, Ordered Set
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 integerval
onto the top of the stack.int pop()
removes and returns the most frequent element in the stack.- If there is a tie for the most frequent element, the element closest to the stack's top 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
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 <= 10^9
- At most
2 * 10^4
calls will be made topush
andpop
. - It is guaranteed that there will be at least one element in the stack before calling
pop
.
Code
C
// 895. Maximum Frequency Stack (12/20/54182)
// Runtime: 421 ms (0.00%) Memory: 67.03 MB (0.00%)
// Macros and functions in sys/mman.h
#define PROT_READ 0x1
#define PROT_WRITE 0x2
#define MAP_ANONYMOUS 0x20
#define MAP_PRIVATE 0x02
#define MAP_FAILED ((void *)-1)
extern void* mmap(void* addr, size_t len, int prot, int flags, int fd, off_t offset);
extern int munmap(void* addr, size_t len);
#define SIZE 10000ULL
#define NUMS 1000000001ULL
typedef struct {
uint16_t most;
uint16_t counts[NUMS];
int stacks[SIZE][SIZE];
uint16_t sizes[SIZE];
} FreqStack;
FreqStack* freqStackCreate() {
return mmap(NULL, sizeof(FreqStack), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
}
void freqStackPush(FreqStack* this, int val) {
int count = ++this->counts[val];
this->stacks[count][++this->sizes[count]] = val;
if (this->most < this->counts[val]) {
this->most = this->counts[val];
}
}
int freqStackPop(FreqStack* this) {
int val = this->stacks[this->most][this->sizes[this->most]--];
this->counts[val]--;
if (this->sizes[this->most] == 0) {
this->most--;
}
return val;
}
void freqStackFree(FreqStack* this) {
munmap(this, sizeof(FreqStack));
}
/**
* Your FreqStack struct will be instantiated and called as such:
* FreqStack* obj = freqStackCreate();
* freqStackPush(obj, val);
* int param_2 = freqStackPop(obj);
* freqStackFree(obj);
*/
JS
// 895. Maximum Frequency Stack (9/29/54182)
// Runtime: 386 ms (77.94%) Memory: 75.94 MB (55.15%)
class FreqStack {
#most = 0;
#counts = {};
#stacks = {};
push(val) {
this.#counts[val] = (this.#counts[val] || 0) + 1;
this.#most = Math.max(this.#most, this.#counts[val]);
if (!this.#stacks[this.#counts[val]]) {
this.#stacks[this.#counts[val]] = [];
}
this.#stacks[this.#counts[val]].push(val);
}
pop() {
const val = this.#stacks[this.#most].pop();
if (this.#stacks[this.#counts[val]--].length === 0) {
this.#most--;
}
return val;
}
};
/**
* Your FreqStack object will be instantiated and called as such:
* var obj = new FreqStack()
* obj.push(val)
* var param_2 = obj.pop()
*/
TS
// 895. Maximum Frequency Stack (9/24/54182)
// Runtime: 303 ms (94.12%) Memory: 72.69 MB (76.47%)
type frequency = number;
class FreqStack {
private most: frequency = 0;
private frequencies: Record<number, frequency> = {};
private stacks: Record<frequency, number[]> = {};
public push(val: number): void {
this.frequencies[val] = (this.frequencies[val] || 0) + 1;
this.most = Math.max(this.most, this.frequencies[val]);
if (!this.stacks[this.frequencies[val]]) {
this.stacks[this.frequencies[val]] = [];
}
this.stacks[this.frequencies[val]].push(val);
}
public pop(): number {
const val = this.stacks[this.most].pop();
if (!this.stacks[this.frequencies[val]--].length) {
this.most--;
}
return val;
}
}
/**
* Your FreqStack object will be instantiated and called as such:
* var obj = new FreqStack()
* obj.push(val)
* var param_2 = obj.pop()
*/