← Bytedance Interview Insights

Bytedance·Software Engineer·Technical Phone Screen·Senior

SeniorPrefer not to say
May 2026Remote

Summary

Bytedance software engineer interview with a classic but brutal LFU cache design problem. The O(1) constraint is what makes it nasty, anyone can brute force it but they want the real thing.

Questions Asked (1)

Q1

Design and implement an LFU (Least Frequently Used) cache class with get and put operations, both running in O(1) average time. On eviction, remove the least frequently used key, and break ties by recency.

Algorithms & Data StructuresSystem Design
Author's notes

The part I fumbled initially was the tie-breaking.

Create a free account to read the full note

AI HintsAI Generated

Suggested Approach

Use a combination of a hash map for O(1) key lookup and a doubly linked list of frequency buckets, where each bucket contains a doubly linked list of keys with the same frequency. On get or put, update the key's frequency and move it to the appropriate bucket, maintaining O(1) operations. On eviction, remove the least frequently used key from the lowest frequency bucket, breaking ties by removing the least recently used key (the tail of that bucket's list).

Pro tip: Mention that you can optimize by using a min-frequency pointer to avoid scanning buckets, and discuss how to handle edge cases like updating an existing key or capacity zero. Also, briefly compare with LRU cache to show deeper understanding.

1. Clarify requirements and constraints

Confirm that get and put must be O(1) average time, eviction policy is LFU with LRU tie-breaking, and discuss edge cases like capacity 0 or 1, and updating existing keys.

2. Design the data structures

Propose a hash map mapping keys to nodes, and a doubly linked list of frequency buckets. Each bucket contains a doubly linked list of keys with that frequency, ordered by recency (most recent at head).

3. Implement get operation

If key exists, retrieve its node, increment its frequency, and move it to the next frequency bucket (creating one if needed). Return the value. If not, return -1.

4. Implement put operation

If key exists, update value and increment frequency similarly to get. If new, insert with frequency 1. If capacity exceeded, evict the least frequently used key (from the lowest frequency bucket, tail for LRU tie-break).

5. Analyze complexity and edge cases

Explain why operations are O(1) average: hash map provides O(1) access, and bucket movements involve constant number of pointer updates. Discuss handling of capacity 0 and updating existing keys.

Key Points to Mention

  • Hash map for O(1) key lookup, storing key-value and frequency information.
  • Doubly linked list of frequency buckets, each bucket containing a doubly linked list of keys with the same frequency.
  • Maintain a min-frequency pointer to quickly access the lowest frequency bucket for eviction.
  • On access (get/put), increment frequency and move key to the next bucket; if bucket becomes empty, remove it and update min-frequency if needed.
  • Eviction: remove the least recently used key from the lowest frequency bucket (tail of the list) to break ties by recency.
  • Time complexity: O(1) average for both get and put due to constant number of pointer updates and hash operations.

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