Deployment Window Scheduler
Reported by candidates from Stripe's online assessment. Pattern, common pitfall, and the honest play if you blank under the timer.
The Stripe Deployment Window Scheduler showed up in reports from October 2026, and it looks scarier than it is. Strip the story and it's interval math on a 10080-minute week. Merge allowed windows, subtract freeze windows, then in part 2 shift everything by a timezone offset and filter. If the OA invite is sitting in your inbox, the hint says queue, but a sorted sweep does the real work. Two parts, eleven tests, and the second part is where people lose points. If you blank on the boundary splitting live, StealthCoder is the quiet safety net running on your screen.
The problem
At Stripe, teams ship changes to services all the time. To keep production stable, the Service Deployments team runs a scheduler that decides when deployments are allowed. Time Format and Window Representation Time is represented as an integer minute_of_week in the range [0, 10079], meaning minutes since Monday 00:00. For example, 0 is Monday 00:00, 60 is Monday 01:00, 1440 is Tuesday 00:00, and 10079 is Sunday 23:59. Every window is represented as start_minute,end_minute and is half-open: it includes start_minute and excludes end_minute. For example, 10,12 covers minutes 10 and 11. Implement scheduleDeploymentWindows. The value of part selects one of the following two stages, and inputCsv contains the corresponding CSV rows. Return the resulting deployment windows as [[start, end],...], sorted by start time. Part 1: Allowed Windows (Tests 1-4) A team defines the times of the week when deployments are allowed. During an incident, the Service Deployments team can also define freeze windows that prevent deployments. A minute is deployable only when it is inside at least one allowed window and inside no freeze window. Compute the week's sorted, continuously deployable windows. For Part 1, part is "part1", and every row in inputCsv has this format: start,end,type The type is either allowed or freeze. Allowed windows may overlap, freeze windows may overlap, and adjacent deployable intervals are returned as one continuous window. Part 1 Source Example part1 540,600,allowed 570,585,freeze The deployable output is [[540,570],[585,600]]. Part 2: Time Zones and Minimum Duration (Tests 5-11) The scheduler now aggregates windows from teams around the world. Each window may use a different local time zone, but all rows contribute to one global calendar and the result must be returned in UTC. For Part 2, part is "part2". The first row of inputCsv contains: utc_now,lead_time_minutes,min_continuous_minutes,k Each remaining row has this format: start,end,type,timezone_offset_minutes The window endpoints are local minute_of_week values for that row's time zone, where local = UTC + timezone_offset_minutes. Convert every window to UTC, normalizing over the 10080-minute week. If a converted interval crosses the weekly boundary, split it at the boundary. After conversion, a minute is deployable when it is inside at least one allowed window and inside no freeze window. A returned UTC window must: start no earlier than utc_now + lead_time_minutes; remain continuously deployable for at least min_continuous_minutes; end no later than minute 10080. Clip deployable intervals to the earliest permitted start, discard any remaining interval that is too short, sort the surviving UTC intervals by start time, and return at most the first k. Return fewer than k windows when fewer valid windows exist. Function scheduleDeploymentWindows(part: String, inputCsv: String[]) → int[][] Examples Example 1 part = "part1" inputCsv = ["540,600,allowed","570,585,freeze"] return = [[540,570],[585,600]] Part 1. The freeze interval removes [570,585) from the allowed interval [540,600). Example 2 part = "part2" inputCsv = ["1020,0,10,5","540,600,allowed,-480","550,565,freeze,-480"] return = [[1020,1030],[1045,1080]] Part 2. The offset converts the allowed interval to [1020,1080) and the freeze interval to [1030,1045). Both remaining windows are at least 10 minutes long. Constraints Weekly minute values are normalized over a 10080-minute week. All intervals are half-open. Window rows use type allowed or freeze.
Reported by candidates. Source: FastPrep
Pattern and pitfall
The trick is to stop thinking about windows and think about minutes. The week is only 10080 minutes, so a difference array or a boolean array per type is simple and fast enough. Mark allowed coverage and freeze coverage with counters, then sweep once and emit runs where allowed > 0 and freeze == 0. Adjacent runs merge automatically because you emit maximal runs. For part 2, convert with utc = (local - offset) mod 10080. If end wraps below start, split into [start,10080) and [0,end). Watch the half-open ends and the case where end equals start after normalization. Then clip each run's start to max(start, utc_now + lead), drop runs shorter than min_continuous, sort, and take the first k. The common bug is clipping after filtering by length instead of before. If the offset math or the wrap split slips away mid-test, StealthCoder is the hedge that gets you unstuck on the live OA.
The honest play: practice the pattern, and have StealthCoder ready for the one you didn't see coming.
You can drill Deployment Window Scheduler 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 for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play.
Get StealthCoderRelated leaked OAs
You've seen the question.
Make sure you actually pass Stripe's OA.
Stripe reuses patterns across OAs. Built for the candidate who saw this exact problem leak two days before his OA and wondered if anyone had a play. Works on HackerRank, CodeSignal, CoderPad, and Karat.
Deployment Window Scheduler FAQ
What's the trick in the Stripe Deployment Window Scheduler?+
Treat the week as 10080 discrete minutes. Use difference arrays for allowed and freeze coverage, sweep once, and emit maximal runs where allowed is positive and freeze is zero. That handles overlaps and adjacency without any special interval merging code.
How do I convert local windows to UTC in part 2?+
Local equals UTC plus offset, so UTC equals local minus offset, taken modulo 10080. Normalize both endpoints. If the normalized end is not greater than the start, split the window at 10080 into two pieces, one ending at the boundary and one starting at 0.
What's the most common mistake on this problem?+
Filtering by minimum duration before clipping to utc_now plus lead time. Clip first, then measure length. Another is mishandling the half-open ends, so [10,12) covers minutes 10 and 11 only. Test your wrap-around split with an example where the window crosses Sunday midnight.
Do I need a queue or heap for this?+
Not really. Despite the queue hint, a sorted event sweep or a plain minute array works. With only 10080 minutes, even the brute force array approach is fast. Pick whichever you can code without bugs under pressure.
How do I prepare for this in 48 hours?+
Practice interval merge and interval subtraction, then a difference array sweep. Write the modulo wrap split once by hand. Run both examples from the prompt, plus one with a freeze that covers an entire allowed window and one with k larger than the result count.