Reported September 2026
Goldman Sachshash table

Notification Deduplication Window

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

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

The mistake that sinks a first attempt on this Goldman Sachs OA, reported September 2026, is forgetting that a suppressed duplicate still refreshes the last-seen time. Miss that and your output goes wrong on example 3 and every long chain of repeats. The problem is a hash map plus a cleanup queue over a nondecreasing timestamp stream. It reads like an easy dedup, but the memory rule and the exact 600-second boundary trip people up. If you blank mid-assessment, StealthCoder runs invisibly on your desktop and gives you a working solution in real time as a safety net.

The problem

A notification service receives a finite batch of arrivals. The arrays notificationIds and timestamps describe the same n arrivals in order. Each timestamp is measured in seconds, and the timestamps are nondecreasing.
Process each arrival using a 600-second deduplication window:
An arrival is a duplicate when the same notification ID was seen less than 600 seconds earlier.
An arrival exactly 600 seconds after the previous sighting is not a duplicate.
Every arrival becomes the new last sighting for its ID, including an arrival that is suppressed as a duplicate.
Return a boolean array in arrival order. Return true for an accepted notification and false for a suppressed duplicate.
Memory requirement
Discard identifiers as soon as their most recent sighting leaves the active window. The retained state must remain proportional to the identifiers still active in the window rather than the total number of processed arrivals.

Function
deduplicateNotifications(notificationIds: String[], timestamps: int[]) → boolean[]

Examples
Example 1
notificationIds = ["A","B","A","A"]
timestamps = [0,100,599,1199]
return = [true,true,false,true]
The arrival of A at 599 is suppressed because it is 599 seconds after the first A. That duplicate refreshes the last-seen time to 599. The final A arrives exactly 600 seconds later, so it is accepted.
Example 2
notificationIds = ["X","X","Y","X","Y"]
timestamps = [42,42,42,641,642]
return = [true,false,true,false,true]
The second X is a duplicate at the same timestamp. The X at 641 is still inside its window, while the Y at 642 is exactly 600 seconds after its previous sighting and is accepted.
Example 3
notificationIds = ["N","N","N","N"]
timestamps = [10,609,1208,1808]
return = [true,false,false,true]
Each suppressed arrival refreshes N, so the arrivals at 609 and 1208 remain duplicates. The final arrival is exactly 600 seconds after the refreshed time 1208 and is accepted.

Constraints
1 <= n <= 2 * 10^5
notificationIds.length == timestamps.length == n
Each value in notificationIds is a non-empty opaque identifier string.
0 <= timestamps[i] <= 10^9
timestamps[i] <= timestamps[i + 1] for every valid i.
Timestamps are measured in whole seconds.

Reported by candidates. Source: FastPrep

Pattern and pitfall

The core is a hash map from ID to last-seen timestamp. For each arrival, look up the ID. If it exists and t - last < 600, output false, otherwise true. Either way, write the new timestamp into the map. That unconditional write is the trap: only updating on accepted arrivals fails example 3. The memory rule needs eviction. Since timestamps are nondecreasing, keep a queue of (id, timestamp) entries. Before processing time t, pop entries from the front while their timestamp <= t - 600, and delete from the map only if the map's value still equals that timestamp. Stale queue entries from refreshed IDs must not delete a newer sighting. Each arrival is pushed and popped once, so it runs in O(n) time with state bounded by the active window. Boundary is strict: exactly 600 is accepted. If the eviction logic gets tangled under time pressure, StealthCoder is the hedge on the live OA.

Memorize the pattern. If you can't, run StealthCoder. The proctor sees the IDE. They don't see what's behind it.

If this hits your live OA

You can drill Notification Deduplication Window 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. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge.

Get StealthCoder

Related leaked OAs

⏵ The honest play

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

Goldman Sachs reuses patterns across OAs. Made by an engineer who treats the OA as theater. If yours is tonight, you don't have time to grind. You have time to hedge. Works on HackerRank, CodeSignal, CoderPad, and Karat.

Notification Deduplication Window FAQ

What's the trick in the Notification Deduplication Window problem?+

Update the last-seen time for every arrival, including suppressed ones. Then treat the boundary correctly: a gap of exactly 600 seconds is accepted, anything under 600 is a duplicate. Those two details decide whether examples 2 and 3 pass.

How hard is this really for a Goldman Sachs OA?+

Easy to medium. The hash map logic is simple. The difficulty is the memory requirement, which forces you to evict expired IDs correctly with a queue, and the refresh rule that makes stale queue entries dangerous.

How do I satisfy the memory requirement?+

Keep a queue of (id, timestamp) in arrival order. Before each arrival at time t, pop front entries with timestamp <= t - 600. Only remove the ID from the map if its stored timestamp equals the popped one, since a later refresh means it's still active.

Can I just use a map without a queue?+

It gives correct output but violates the stated memory requirement, since state grows with total distinct IDs. Because timestamps are nondecreasing, a queue gives clean amortized O(1) eviction, so add it.

How do I prepare for this in 48 hours?+

Write it once from scratch with a map and a deque, then test the three given examples by hand. Add your own case with a long chain of suppressed repeats and a gap of exactly 600. That covers the failure modes.

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

OA at Goldman Sachs?
Invisible during screen share
Get it