LRU Cache with TTL Expiration
Reported by candidates from TikTok's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
You're facing TikTok's LRU Cache with TTL Expiration problem in May 2026. This is a hybrid design question that tests two things at once: LRU eviction logic and time-based expiration. The trick is handling the order of operations correctly. Before every get or put, you must sweep expired keys. Only then do you check capacity and evict if needed. Most candidates trip up on the sweep timing or forget to update the recency rank when a key is refreshed. StealthCoder will spot the exact condition you need to check before each operation.
The problem
Implement a fixed-capacity LRU cache that also supports per-entry TTL expiration. You are given the cache capacity, an array of operation names, and a parallel array of integer arguments. Process the operations in order and return one output string for each get operation. Each operation has a timestamp as its first argument. Timestamps are non-decreasing. put has arguments [time, key, value, ttl]. It inserts or updates key with value. The key expires at absolute time time + ttl. Updating an existing key replaces both its value and expiration time. A successful put makes the key most recently used. get has arguments [time, key]. If the key exists and has not expired, return its value as a string and make the key most recently used. Otherwise, return "-1". Before processing each operation, remove every expired key. A key is expired when current time >= expiration time. If a put causes the cache to exceed capacity after expired keys have been removed, evict the least recently used remaining key. Function Description Complete solveLRUCacheTTL. It has the following parameters: int capacity: the maximum number of live keys in the cache String[] operations: each value is either "put" or "get" int[][] arguments: arguments for each operation, using the formats above Return a String[] containing the outputs of all get operations in order. Key 1 expires at time 5, so it is gone before the operation at time 6. Keys 2 and 3 expire at time 11, so the final get at time 12 misses. The second put updates key 5 and extends its expiration. Later, inserting key 6 into a capacity-1 cache evicts key 5. 1 <= capacity <= 10^5 1 <= operations.length == arguments.length <= 10^5 operations[i] is either \"put\" or \"get\" For put, arguments[i] has length 4: [time, key, value, ttl] For get, arguments[i] has length 2: [time, key] Timestamps are non-decreasing and all TTL values are positive. Use an O(operations.length) or O(operations.length log operations.length) approach.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The pattern here is pure design, but it's really two data structures working together. You need a hash map for O(1) lookup and a doubly linked list for O(1) LRU tracking. The key insight: expiration happens at a point in time, not on an interval. When time >= (insertion_time + ttl), the key is gone. Before processing each operation, iterate through all cached keys and remove any that have expired. Only after cleanup do you handle the actual get or put. If a put triggers an overflow, evict from the tail of your LRU list. If you're blanking on the linked-list mechanics during the live OA, StealthCoder will feed you the structure and the pointer-twiddling pattern in real time.
StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.
You can drill LRU Cache with TTL Expiration cold, or you can hedge it. StealthCoder runs invisibly during screen share and surfaces a working solution in under 2 seconds. The proctor sees the IDE. They don't see what's behind it. If you're reading this with an OA window open, you're who this was built for.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as lru cache. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass TikTok's OA.
TikTok reuses patterns across OAs. If you're reading this with an OA window open, you're who this was built for. Works on HackerRank, CodeSignal, CoderPad, and Karat.
LRU Cache with TTL Expiration FAQ
How do I know when a key expires?+
A key expires when the current operation's timestamp is greater than or equal to the key's expiration time (insertion_time + ttl). Before every get or put, scan all keys and remove any that have expired. Expiration is absolute, not relative.
What's the order of operations within a single get or put?+
First, sweep all expired keys. Second, handle the actual get or put. Third, if it's a put that causes overflow, evict the least recently used key. This order matters because expiration removes capacity, which might prevent you from needing to evict.
Does updating a key's value change its LRU rank?+
Yes. Putting a new value into an existing key moves it to the most recently used position, as if you'd just inserted it fresh. This also resets its TTL to the new time + ttl value.
What data structure should I use?+
Hash map for O(1) key lookups, and a doubly linked list for O(1) LRU insertion and eviction. Store the expiration time with each node. The sweep itself is O(n) per operation, which is acceptable given the constraints.
Is there a trick to pass in under the time limit?+
No exotic trick. Just implement the sweep, the hash-doubly-linked-list pair, and be careful with pointer updates. If you're using a language with built-in ordered collections like Python's OrderedDict, use it. Focus on correctness first.