Time-Based Key-Value Map With Floor and Ceiling Queries
Reported by candidates from Character.AI's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
Character.AI reported this one in April 2025, and the detail that bites is the CEIL operation sitting next to GET. It looks like the classic time-based key-value store, but out-of-order SETs and a ceiling lookup change the data structure you need. You've got up to 100000 operations, so a linear scan per query will die. This is a hash table of per-key ordered timestamps, with binary search on top. If you blank on how to keep the timestamps sorted while inserting, StealthCoder is the invisible safety net running during the live OA.
The problem
Process operations on a time-based key-value map. SET stores or replaces a value for a key at a timestamp and contributes null to the result. GET contributes the value at the greatest stored timestamp less than or equal to the query timestamp. CEIL contributes the value at the smallest stored timestamp greater than or equal to the query timestamp. A missing answer contributes the empty string. SET timestamps may arrive out of order. When the same key and timestamp is set again, the latest value replaces the earlier one. Process operations in array order and return one result per operation. Function runVersionedMap(operations: String[], keys: String[], values: String[], timestamps: int[]) → String[] Examples Example 1 operations = ["SET","SET","GET","CEIL"] keys = ["a","a","a","a"] values = ["late","early","",""] timestamps = [10,2,7,7] return = ["null","null","early","late"] The out-of-order writes are sorted by timestamp for both floor and ceiling lookup. Example 2 operations = ["SET","SET","GET","CEIL","SET","GET"] keys = ["x","x","x","x","x","x"] values = ["old","new","","","replacement",""] timestamps = [5,9,4,6,5,5] return = ["null","null","","new","null","replacement"] Missing floor lookup is empty, ceiling finds timestamp 9, and a repeated timestamp is overwritten. Constraints 1 <= operations.length <= 100000 All four input arrays have equal length. Each operation is SET, GET, or CEIL. 1 <= timestamps[i] <= 10^9 Keys and SET values are nonempty strings of length at most 100.
Reported by candidates. Source: FastPrep
Pattern and pitfall
Map each key to a sorted structure of timestamps and values. GET is a floor lookup, CEIL is a ceiling lookup, and both are binary search on that sorted structure. The catch is that SET arrives out of order and can overwrite an existing timestamp. A plain array with append breaks, because you'd need to insert in the middle, which is O(n) per insert. In Java or C++, use a TreeMap or std::map per key with floorKey and ceilingKey or lower_bound. In Python, no built-in sorted map exists, so use bisect with insort and a parallel dict for values. Check for an existing timestamp first, then overwrite without inserting a duplicate. Return the string null for SET and the empty string for misses. Pitfall: mixing those two up. If the structure feels heavy and you freeze live, StealthCoder is the hedge that gets you a working version.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Time-Based Key-Value Map With Floor and Ceiling Queries 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 would have shipped this the night before his JPMorgan OA if he'd had it.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Character.AI's OA.
Character.AI reuses patterns across OAs. Built by an Amazon engineer who would have shipped this the night before his JPMorgan OA if he'd had it. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Time-Based Key-Value Map With Floor and Ceiling Queries FAQ
What's the trick in this Character.AI OA question?+
Keep a hash map from key to a sorted collection of timestamps. GET is a floor search and CEIL is a ceiling search. Out-of-order SETs mean you can't just append, so you need a sorted map or bisect-based insertion. Overwrite on equal timestamps instead of adding a duplicate.
How hard is this really?+
Medium. It's the familiar time-based key-value store plus a ceiling query and out-of-order writes. If you know TreeMap or bisect, it's quick. The difficulty is picking a structure that handles sorted insertion efficiently at 100000 operations.
What's the return value for SET versus a missing lookup?+
SET contributes the literal string null. A GET or CEIL with no matching timestamp contributes the empty string. Examples 1 and 2 show both. Mixing these up is the most common way to fail hidden tests on an otherwise correct solution.
Will a sorted array with insertion pass the time limits?+
Risky. Binary search finds the position in log n, but inserting into the middle of an array shifts elements, costing O(n). With 100000 operations on one key that can get slow. A balanced tree map is safer where available, and bisect insort is often acceptable in practice.
How do I prepare for this in 48 hours?+
Solve the standard time-based key-value store once, then add a ceiling lookup and an overwrite case. Practice floor and ceiling binary search by hand, and know your language's sorted map or bisect API. Test the two examples, plus repeated timestamps and missing keys.