The O(n) Club: Maximum Frequency Stack, But Cooler: The Stack That Never Forgets (or Forgives)

The O(n) Club: Maximum Frequency Stack, But Cooler

⚡ TL;DR

Your classic stack is LIFO: “Last one in, first one out.” But what if the boss suddenly wants you to pop the element that’s shown up most often? Enter Frequency Stack—a data structure with trust issues! You use maps to track who’s most popular and group stacks to track recency. In Java, it’s almost magic (minus the wand):

// Sketchy, but true summary
void push(int x) {
    int freq = freqMap.getOrDefault(x, 0) + 1;
    freqMap.put(x, freq);
    group.computeIfAbsent(freq, z -> new Stack<>()).push(x);
    maxFreq = Math.max(maxFreq, freq);
}
 int pop() {
    int x = group.get(maxFreq).pop();
    freqMap.put(x, freqMap.get(x) - 1);
    if (group.get(maxFreq).isEmpty()) maxFreq--;
    return x;
}

🧠 How Devs Usually Mess This Up

Look, if you use a regular stack, congratulations, you’ve made another boring stack. If you use a max heap, you’ll need timestamps or a crystal ball to settle tiebreakers. And if you accidentally track frequency per stack frame? You might as well code on a potato. Bottom line: the rookie moves here are assuming LIFO is enough, forgetting about ties, and mismanaging frequency like it’s a gym subscription.

🔍 What’s Actually Going On

This problem wants you to act like a nightclub bouncer with an Excel sheet—let the most frequent (and loudest) patron leave first, but if there’s a tie? The one who yelled most recently gets kicked out.
Practically, you need:

  • freqMap: Maps each element to its frequency—keeps you from making stuff up.
  • group: A stack for each frequency—so you always know which guests are double-dipping.
  • maxFreq: The current most-annoying frequency.

Every push() drops your element on the stack for its frequency; every pop() grabs the latest from the stack with the highest frequency, then hands out a “please leave” coupon as you decrement its count.

🛠️ PseudoCode

  • Push(x):
    • Increment freqMap[x]
    • If this is a new frequency, make a new stack in group
    • Push x onto group[freq]
    • maxFreq = bigger of old maxFreq or freq
    freq = freqMap.getOrDefault(x, 0) + 1;
    freqMap.put(x, freq);
    group.computeIfAbsent(freq, z -> new Stack<>()).push(x);
    maxFreq = Math.max(maxFreq, freq);
    
  • Pop():
    • Pop top item from group[maxFreq]
    • Decrement its frequency in freqMap
    • If group[maxFreq] is now empty, reduce maxFreq
    • Return x (congratulations, you yeeted the worst offender)
    x = group.get(maxFreq).pop();
    freqMap.put(x, freqMap.get(x) - 1);
    if (group.get(maxFreq).isEmpty()) maxFreq--;
    return x;
    

💻 The Code

import java.util.*;
 class FreqStack {
    private Map<integer integer> freqMap = new HashMap<>();
    private Map<integer stack>> group = new HashMap<>();
    private int maxFreq = 0;
     public void push(int x) {
        int freq = freqMap.getOrDefault(x, 0) + 1;
        freqMap.put(x, freq);
        group.computeIfAbsent(freq, z -> new Stack<>()).push(x);
        maxFreq = Math.max(maxFreq, freq);
    }
     public int pop() {
        Stack
<integer> stack = group.get(maxFreq);
        int x = stack.pop();
        freqMap.put(x, freqMap.get(x) - 1);
        if (stack.isEmpty()) maxFreq--;
        return x;
    }
     public static void main(String[] args) {
        FreqStack fs = new FreqStack();
        fs.push(5); fs.push(7); fs.push(5); fs.push(7); fs.push(4); fs.push(5);
        System.out.println(fs.pop()); // 5
        System.out.println(fs.pop()); // 7
        System.out.println(fs.pop()); // 5
        System.out.println(fs.pop()); // 4
    }
}
</integer></integer></integer>

⚠️ Pitfalls, Traps & Runtime Smacks

  • Empty Stack Drama: Pop when the stack is empty, and Java will repay you—with a runtime error as dramatic as your bug tracker.
  • maxFreq Slip-Ups: Always update maxFreq—otherwise, you might pop from an empty stack (awkward silence).
  • Tie-breakers: Never trust hash order. Always break ties with recency using real stacks.
  • Performance Hype: Both push() and pop() are O(1). Yes, that’s real. No, LinkedList O(1) memes here.

🧠 Interviewer Brain-Tattoo

“A regular stack is forgetful. A frequency stack? Unforgiving, petty, and always keeping score.”

Previous Article

The O(n) Club: Spiral Matrix II: Mastering The Swirly-Square Algorithm Without Losing Your Sanity

Next Article

The O(n) Club: Sort Array By Parity: When Evens Take the Lead (and Odds Wait in Line)