Keep Endpoints and Strict Local Maxima
Reported by candidates from ZipRecruiter's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The ZipRecruiter OA reported in September 2024 hands you an array and one odd rule: always keep the first and last values, and keep an interior value only if it's strictly greater than both neighbors. Empty returns empty, and a singleton comes back once. That's a single-pass array scan, nothing fancier. The risk isn't difficulty, it's sloppy edge cases when you're typing fast under a timer. If you blank on the boundary handling, StealthCoder runs invisibly during the live OA and can give you a working solution as a safety net. Know the shape of it before you start anyway.
The problem
Return selected values in original order. Always keep the first and last values. Keep an interior value only when it is strictly greater than both immediate neighbors. An empty array returns empty, and a singleton is returned once. Function keepLocalMaxima(values: int[]) → int[] Examples Example 1 values = [1,2,1] return = [1,2,1] The strict interior peak joins both endpoints. Example 2 values = [1,2,3] return = [1,3] Only the endpoints remain. Constraints 0 <= values.length <= 100000 -1000000000 <= values[i] <= 1000000000
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is to treat endpoints separately from the interior. If length is 0, return empty. If length is 1, return the single value once, not twice. Otherwise push values[0], loop i from 1 to n-2, push values[i] when it's strictly greater than values[i-1] and values[i+1], then push values[n-1]. That's O(n) time and O(n) output space. The common pitfall is the singleton, where naively adding first and last duplicates the element. The second is using >= instead of >, which wrongly keeps plateaus like [1,2,2,1]. Neither 2 is a strict peak there, so both get dropped. Values go up to 1e9 in magnitude, but you're only comparing, so no overflow concerns. If you freeze on these edge cases during the live OA, StealthCoder is the hedge that keeps you moving.
If this hits your live OA and you blank, StealthCoder solves it in seconds, invisible to the proctor.
You can drill Keep Endpoints and Strict Local Maxima 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 ZipRecruiter's OA.
ZipRecruiter 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.
Keep Endpoints and Strict Local Maxima FAQ
How hard is the ZipRecruiter keep local maxima question really?+
Easy. It's one linear pass with a couple of edge cases. The difficulty is purely in not missing the empty and singleton rules. If you can write a for loop and compare neighbors, you can solve it in a few minutes.
What's the trick to this problem?+
Handle endpoints outside the loop. Add the first value, loop over indices 1 through n-2 checking strict greater-than against both neighbors, then add the last value. Guard n == 0 and n == 1 up front so you don't duplicate or crash.
Why does a plateau like [1,2,2,1] matter?+
The rule says strictly greater than both immediate neighbors. With two equal 2s, neither beats the other, so neither is kept. Only the endpoints 1 and 1 remain. Using >= would wrongly keep them, which is the most common wrong answer.
What are the edge cases I should test?+
Test an empty array, a single element, two elements, a strictly increasing array, a strictly decreasing array, and a plateau. Two elements should return both, since both are endpoints. Also try negatives and the 1e9 extremes, though comparisons won't overflow.
How do I prepare for this in 48 hours?+
Practice a few array scans with neighbor comparisons and boundary guards. Write this one from scratch twice, including the edge cases. Aim for clean O(n) code with no index-out-of-range errors. That's enough for a problem at this level.