← Uber Interview Insights

Uber·Software Engineer·Technical Phone Screen·Senior

SeniorPrefer not to say
Jun 2026Remote

Summary

Uber SWE interview that went deep into data structure design, specifically around streaming frequency tracking. The kind of problem that sounds manageable until you're actually on the spot trying to justify every complexity claim.

Questions Asked (1)

Q1

Design a data structure that tracks the top-K most frequent keys in a stream, supporting increment, decrement, and topK operations with O(1) amortized updates.

Algorithms & Data StructuresSystem DesignTechnical Trade-offs
Author's notes

I knew the hash map part immediately but fumbled explaining why the doubly linked list of frequency buckets actually gives you O(1).

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Start by clarifying requirements: stream of keys, operations increment(key), decrement(key), and topK() returning K most frequent keys. Propose a hybrid data structure combining a hash map for O(1) frequency lookup and a doubly linked list of frequency buckets, where each bucket contains a set of keys with that frequency. For topK, maintain a separate min-heap of size K or a sorted list of buckets to retrieve top K efficiently.

Pro tip: Mention that the bucket list approach gives O(1) amortized updates because each increment/decrement moves a key at most one bucket, and topK can be O(K) by traversing from the highest frequency bucket. Also note that if K is small, a heap is simpler, but for large K the bucket list is better.

1. Clarify requirements and constraints

Ask about stream size, K value, whether decrement can make frequency negative, and if topK needs to be sorted. Confirm O(1) amortized for updates and discuss expected topK complexity.

2. Propose core data structures

Use a hash map from key to its frequency and a node in a doubly linked list of frequency buckets. Each bucket holds a set of keys with the same frequency. Maintain buckets in increasing order of frequency.

3. Detail increment and decrement operations

For increment: look up key, move it to the next higher frequency bucket (create if needed), update hash map. For decrement: move to previous bucket, remove key if frequency becomes zero. Both are O(1) amortized because each move is constant time.

4. Design topK operation

Traverse buckets from highest frequency downward, collecting keys until K are gathered. If K is large, consider maintaining a min-heap of size K updated on each frequency change, but that adds O(log K) per update. Discuss trade-offs.

5. Analyze complexity and edge cases

State that updates are O(1) amortized, topK is O(K) with bucket traversal. Handle edge cases: empty stream, K larger than distinct keys, decrement below zero, and concurrent access if needed.

Key Points to Mention

  • Hash map for O(1) frequency lookup and key-to-bucket mapping
  • Doubly linked list of frequency buckets with sets of keys
  • O(1) amortized updates by moving keys between adjacent buckets
  • TopK retrieval by traversing buckets from highest frequency
  • Trade-off between bucket list and heap for topK (O(K) vs O(log K) updates)
  • Handling decrement to zero and removing empty buckets

AI-generated suggestions, not part of the candidate's original notes. May be inaccurate — verify before relying on them.