Time Based Key-Value Store
Reported by candidates from Navan's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The whole Navan question from December 2025 comes down to one data structure: a hash map from key to a list of (timestamp, value) pairs, searched with binary search. It's the time-based key-value store, wrapped in a function that takes four parallel arrays and returns strings. If you've got an OA invite for Navan, expect this shape. The logic is short, but the setup trips people up. StealthCoder sits invisibly on your screen as a safety net if you blank mid-assessment, but the pattern below is simple enough to carry in your head.
The problem
Process set and get operations on a time-based key-value store. A get returns the value written for that key at the greatest timestamp not exceeding the query timestamp, or the empty string when none exists. Return "null" for set operations. Function runTimeMap(operations: String[], keys: String[], values: String[], timestamps: int[]) → String[] Examples Example 1 operations = ["set","get","get","set","get"] keys = ["foo","foo","foo","foo","foo"] values = ["bar","","","bar2",""] timestamps = [1,1,3,4,4] return = ["null","bar","bar","null","bar2"] Each query sees the most recent value for foo at or before its timestamp. Constraints All four arrays have equal non-zero length. Set timestamps for each key are strictly increasing. There are at most 100000 operations.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Store each key's writes in a list. The constraints say set timestamps per key are strictly increasing, so appending keeps each list sorted for free. No sorting needed. For a get, binary search that key's list for the largest timestamp less than or equal to the query. If none qualifies, return the empty string. The common pitfall is off-by-one in the search. Use an upper-bound style search, then step back one index. Another trap is the output format. Set operations must return the string "null", not a real null. Get operations ignore the values array entry, which is empty. With up to 100000 operations, a linear scan per get could blow up, so binary search matters. Each get costs O(log n). If you freeze on the bisect boundary during the live OA, StealthCoder is the hedge that gives you a working version fast.
If you see this problem in your OA tomorrow, the play is to recognize the pattern in 30 seconds. StealthCoder buys you that recognition.
You can drill Time Based Key-Value Store 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. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken.
Get StealthCoderRelated leaked OAs
This OA pattern shows up on LeetCode as time based key value store. If you have time before the OA, drill that.
You've seen the question.
Make sure you actually pass Navan's OA.
Navan reuses patterns across OAs. Built by an Amazon engineer who passed his OA cold and still thinks the filter is broken. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Time Based Key-Value Store FAQ
What's the trick in the Navan time-based key-value store question?+
Map each key to a list of (timestamp, value) pairs and binary search on get. Because set timestamps per key are strictly increasing, appending keeps the list sorted. You want the greatest timestamp at or below the query, so find the rightmost match.
How hard is this problem really?+
Medium-easy if you know bisect. The logic is about 20 lines. Most failures come from the boundary condition in the search or from forgetting that set operations return the string "null". Write the example by hand once and you'll catch both.
What should get return when no timestamp qualifies?+
The empty string. This happens when the key was never set, or every write for that key has a timestamp greater than the query. Check for the missing key first, then check whether the binary search landed before index zero.
Can I just scan the list linearly on each get?+
With up to 100000 operations, a linear scan can degrade to quadratic time on a single hot key. Binary search keeps each get at O(log n). It's barely more code, so just do it right the first time.
How do I prepare for this in 48 hours?+
Write the solution from scratch twice. Practice the upper-bound binary search until it's automatic. Then trace the Navan example by hand, including the set at timestamp 4 and the get at timestamp 4. Also practice mapping parallel input arrays to operations, since that wrapper is the unusual part.