Reported October 2026
Appledesign

LRU Cache

Reported by candidates from Apple's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.

Get StealthCoderRuns invisibly during the live Apple OA. Under 2s to a working solution.
Founder's read

The mistake that sinks most first attempts at this Apple OA, reported in October 2026, is treating PUT on an existing key as a plain insert. It isn't. An update has to refresh recency too, or your eviction order is wrong and a hidden test fails. The problem is LRU Cache wrapped in a string-operations harness: parse each line, run GET or PUT, collect GET results. Capacity goes up to 100000 and operations up to 200000, so O(1) per operation is the target. If you blank on the pointer wiring mid-assessment, StealthCoder is the safety net running invisibly on your screen.

The problem

Implement a least recently used cache with fixed positive capacity, then process the operations in operations.
"PUT key value" inserts or updates a key. When a new key would exceed capacity, evict the least recently used key.
"GET key" returns the stored value, or -1 when the key is absent.
A successful GET and every PUT make that key the most recently used. A missing GET does not change recency. Return the results of all GET operations in their original order.
Build the cache behavior directly; do not use a library-provided LRU cache.

Function
runLRU(capacity: int, operations: String[]) → int[]

Examples
Example 1
capacity = 2
operations = ["PUT 1 10","PUT 2 20","GET 1","PUT 3 30","GET 2","GET 3"]
return = [10,-1,30]
GET 1 makes key 1 recent, so inserting key 3 evicts key 2.
Example 2
capacity = 1
operations = ["PUT 4 7","PUT 4 9","GET 4","PUT 5 5","GET 4"]
return = [9,-1]
Updating key 4 changes its value to 9. Inserting key 5 later evicts it because capacity is 1.
Example 3
capacity = 2
operations = ["GET 7","PUT 0 0","GET 0"]
return = [-1,0]
The first lookup misses without changing the cache. Keys and values may be zero.

Constraints
1 <= capacity <= 100000.
1 <= operations.length <= 200000.
Every operation is exactly "GET key" or "PUT key value".
-10^9 <= key, value <= 10^9.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The trick is a hash map plus a doubly linked list. The map takes key to node for O(1) lookup. The list keeps recency order, with the head side as most recent and the tail side as least recent. Use dummy head and tail nodes so you never special-case empty or single-node lists. GET hit: move the node to the front and return its value. GET miss: return -1 and touch nothing. PUT existing: update the value and move to front. PUT new: if size equals capacity, remove the tail's previous node and delete its key from the map, then insert at the front. Pitfalls: forgetting to delete the evicted key from the map, parsing negative numbers badly, and using a library LRU, which the problem bans. Keys and values can be zero or negative, so don't use falsy checks. StealthCoder is the hedge if the pointer order slips under pressure in the live OA.

StealthCoder is the hedge for the one pattern you didn't drill. It runs invisibly during the screen share.

If this hits your live OA

You can drill LRU Cache 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 StealthCoder

Related leaked OAs

⏵ Practice the LeetCode equivalent

This OA pattern shows up on LeetCode as lru cache. If you have time before the OA, drill that.

⏵ The honest play

You've seen the question. Make sure you actually pass Apple's OA.

Apple 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 FAQ

How hard is this Apple LRU Cache OA really?+

It's a medium that feels harder under a timer. The idea is well known, but the linked list pointer updates are easy to botch. If you've written it once with dummy head and tail nodes, it's maybe 25 lines of real logic plus parsing.

What's the trick to get O(1) per operation?+

Pair a hash map with a doubly linked list. The map finds the node instantly, and the list lets you remove and reinsert it at the front without scanning. Eviction pops the node before the dummy tail. Arrays or scanning for the oldest key will time out at 200000 operations.

What's the most common bug on this problem?+

Not refreshing recency on a PUT that updates an existing key. Example 2 hints at it. The second most common is evicting from the list but leaving the key in the map, which makes later GETs return stale values instead of -1.

Can I use LinkedHashMap or OrderedDict?+

No. The problem says to build the cache behavior directly and not use a library-provided LRU cache. Building the map plus linked list yourself is the safe route, and it's what the grader expects you to show.

How do I prepare for this in 48 hours?+

Write the map plus doubly linked list version from scratch twice, with helper methods for remove and addToFront. Then add the input parsing: split each string on spaces, convert to ints, and append only GET results to the output. Test with the three examples, including zero keys.

Problem reported by candidates from a real Online Assessment. Sourced from a publicly-available candidate-aggregated repository. Not affiliated with Apple.

OA at Apple?
Invisible during screen share
Get it