Frequency Stack with Recency Tie-Breaking
AmazonSoftware Engineer · Technical ScreenLast updated
Design a frequency stack data structure that supports pushing elements and popping the most frequent element, breaking ties by choosing the most recently pushed element, with both operations running in O(1) time.
Frequency Stack with Recency Tie-Breaking
Design a stack-like data structure that retrieves and removes elements based on their frequency of occurrence, breaking ties using the element's recency (LIFO order).
Implement the FreqStack class:
FreqStack(): Initializes an empty frequency stack.push(val: int) -> None: Pushes an integervalonto the top of the stack.pop() -> int: Removes and returns the most frequent element in the stack. If there is a tie for the most frequent element, it removes and returns the element that was pushed closest to the top (i.e., the most recent one among the tied elements).
Both push and pop should operate in O(1) average time complexity.
Method Signatures
class FreqStack:
def __init__(self):
pass
def push(self, val: int) -> None:
pass
def pop(self) -> int:
pass
Example 1
Input:
freq_stack = FreqStack()
freq_stack.push(5)
freq_stack.push(7)
freq_stack.push(5)
freq_stack.push(7)
freq_stack.push(4)
freq_stack.push(5)
freq_stack.pop() -> returns 5
freq_stack.pop() -> returns 7
freq_stack.pop() -> returns 5
freq_stack.pop() -> returns 4
Explanation:
After pushing [5, 7, 5, 7, 4, 5]:
- Frequency map: 5 -> 3, 7 -> 2, 4 -> 1
- First pop(): 5 has the highest frequency (3). Return 5. Frequency of 5 becomes 2.
- Second pop(): Both 5 and 7 have frequency 2. 7 was pushed more recently than 5 at this frequency level. Return 7. Frequency of 7 becomes 1.
- Third pop(): 5 has frequency 2, 7 has 1, 4 has 1. 5 has highest frequency. Return 5. Frequency of 5 becomes 1.
- Fourth pop(): 7, 4, and 5 all have frequency 1. 4 is the most recent. Return 4.
Constraints
0 <= val <= 10^9- At most
2 * 10^5calls will be made topushandpop. - It is guaranteed that
popwill not be called on an empty stack.
Edge Cases to Consider
- All elements having distinct values (degenerates into a standard LIFO stack).
- Multiple elements sharing the same maximum frequency.
- A single element pushed and popped multiple times repeatedly.
Hints
Hint 1
Track the frequency of each element using a hash map.
Hint 2
To resolve ties by recency, group elements by their frequency level using a stack for each frequency count.
Hint 3
Maintain a variable for the current maximum frequency; when the stack for that frequency empties, decrement the maximum frequency.
Follow-up questions
- How would you implement a peek() method that returns the element pop() would return, without removing it, while maintaining O(1) time?
- How would you make this data structure thread-safe for high-concurrency read and write workloads?
- If memory is constrained and values are drawn from a small bounded range, how could you optimize the memory footprint?
Solution walkthrough is for members
Get the full walkthrough with reference code and complexity analysis, plus Kitty Coach at 300 messages a day. Hints, the code runner and community answers stay free.