Problem Statement
Insert Interval
An interval is just a pair of numbers, a start and an end, like [2,5]. Think of it as a busy block of time on a calendar, say from 2 o'clock to 5 o'clock. You are given a list of these busy blocks, already sorted by start time, and none of them overlap each other. Then you get one new block to add. Your job is to slot it in, and if it bumps into any existing blocks (they share time), glue them together into one bigger block. The trick that makes this easy: because the list is already sorted, you can sweep through it left to right in three clean phases. First handle the blocks that come fully before the new one, then merge anything that touches it, then handle the blocks that come fully after.
Signals to notice
Brute force first
Add the interval, re-sort, then merge. Doesn't exploit the already-sorted structure. It is a fair place to begin because it matches the surface of the question, yet it does not capture the deeper structure that makes the problem simpler.
The key insight
Three phases: (1) add all intervals that end before newInterval starts (no overlap). (2) Merge all overlapping intervals with newInterval. (3) Add all intervals that start after newInterval ends. Once you hold onto the right piece of information from moment to moment, the problem feels less like trial and error and more like following a shape that was there all along.
Trace it on intervals=[[1,3],[6,9]], newInterval=[2,5]
init: result=[], i=0, newInterval=[2,5] Phase1 (end < 2): intervals[0][1]=3 not < 2 -> stop, nothing added, i=0 Phase2 (start <= 5): intervals[0][0]=1 <= 5 -> merge newInterval=[min(2,1),max(5,3)]=[1,5], i=1 Phase2: intervals[1][0]=6 not <= 5 -> stop; append newInterval -> result=[[1,5]] Phase3 (add rest): append intervals[1]=[6,9] -> result=[[1,5],[6,9]], i=2 return [[1,5],[6,9]]
What must stay true
The intervals are already sorted and non-overlapping. The new interval can only overlap with a contiguous run of existing intervals — everything before and after is independent. When you keep that truth intact, each local choice supports the larger solution instead of fighting it.
Shape of the loop
result = []; i = 0
while i<n and intervals[i].end < new.start: result.add(intervals[i]); i++
while i<n and intervals[i].start <= new.end:
new = [min(new.start,intervals[i].start), max(new.end,intervals[i].end)]; i++
result.add(new)
while i<n: result.add(intervals[i]); i++ # return resultPseudocode only — the full worked solution lives in the Solution tab.
Easy way to go wrong
Not merging transitively — the new interval might overlap with multiple existing intervals. Keep extending the merge while overlap exists. When the code becomes mechanical before the idea is clear, small edge cases start breaking the whole story.