Insert Interval into Sorted List in DSA Go - Time & Space Complexity
We want to understand how the time needed to insert a new interval into a sorted list of intervals grows as the list gets bigger.
Specifically, how does the number of steps change when we add more intervals?
Analyze the time complexity of the following code snippet.
func insertInterval(intervals [][]int, newInterval []int) [][]int {
var result [][]int
i := 0
n := len(intervals)
for i < n && intervals[i][1] < newInterval[0] {
result = append(result, intervals[i])
i++
}
for i < n && intervals[i][0] <= newInterval[1] {
newInterval[0] = min(newInterval[0], intervals[i][0])
newInterval[1] = max(newInterval[1], intervals[i][1])
i++
}
result = append(result, newInterval)
for i < n {
result = append(result, intervals[i])
i++
}
return result
}
func min(a, b int) int {
if a < b {
return a
}
return b
}
func max(a, b int) int {
if a > b {
return a
}
return b
}
This code inserts a new interval into a sorted list of intervals, merging overlapping intervals as needed.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Three separate loops that each traverse parts of the intervals list.
- How many times: Each loop runs over a portion of the list without overlap, together covering all intervals once.
As the number of intervals (n) grows, the code checks each interval at most once in one of the loops.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks and merges |
| 100 | About 100 checks and merges |
| 1000 | About 1000 checks and merges |
Pattern observation: The number of operations grows roughly in direct proportion to the number of intervals.
Time Complexity: O(n)
This means the time to insert and merge intervals grows linearly with the number of intervals in the list.
[X] Wrong: "Since there are three loops, the time complexity is O(3n) or O(n^2)."
[OK] Correct: The loops run one after another and together cover each interval only once, so the total work is proportional to n, not n squared.
Understanding this linear time complexity helps you explain how your solution efficiently handles merging intervals without unnecessary repeated work.
"What if the intervals list was not sorted? How would the time complexity change?"
Practice
Solution
Step 1: Understand the problem context
The list contains sorted, non-overlapping intervals. Inserting a new interval may cause overlaps.Step 2: Determine the correct action
We must merge any overlapping intervals with the new one to keep the list sorted and non-overlapping.Final Answer:
To merge overlapping intervals and keep the list sorted -> Option AQuick Check:
Insert interval = merge and keep sorted [OK]
- Just appending without merging
- Removing intervals incorrectly
- Sorting again after insertion
Solution
Step 1: Identify slice of slices syntax
In Go, [][]int means a slice of slices of int, suitable for intervals like [start, end].Step 2: Check each option
intervals := [][]int{{1, 3}, {6, 9}} correctly uses [][]int with nested slices for intervals. intervals := [][2]int{{1, 3}, {6, 9}} uses array [2]int which is valid but less common. intervals := []int{1, 3, 6, 9} is a flat slice, not intervals. intervals := [][]int{1, 3, 6, 9} is invalid syntax.Final Answer:
intervals := [][]int{{1, 3}, {6, 9}} -> Option DQuick Check:
Slice of slices = [][]int{{start,end}} [OK]
- Using flat []int instead of [][]int
- Incorrect array vs slice syntax
- Missing curly braces for nested slices
intervals := [][]int{{1, 2}, {6, 9}}
newInterval := []int{2, 5}
// After insertion and merging
result := [][]int{{1, 5}, {6, 9}}
fmt.Println(result)Solution
Step 1: Insert and check overlap
New interval [2,5] overlaps with [1,2] because 2 <= 2. Merge them to [1,5].Step 2: Keep other intervals
[6,9] does not overlap with [1,5], so it stays as is.Final Answer:
[[1 5] [6 9]] -> Option CQuick Check:
Merged intervals = [[1 5] [6 9]] [OK]
- Not merging overlapping intervals
- Appending new interval without sorting
- Incorrect interval order
func insert(intervals [][]int, newInterval []int) [][]int {
var result [][]int
for _, interval := range intervals {
if interval[1] < newInterval[0] {
result = append(result, interval)
} else if interval[0] > newInterval[1] {
result = append(result, newInterval)
newInterval = interval
} else {
newInterval[0] = min(newInterval[0], interval[0])
newInterval[1] = max(newInterval[1], interval[1])
}
}
result = append(result, newInterval)
return result
}Solution
Step 1: Analyze appending logic
When interval[0] > newInterval[1], newInterval is appended and then replaced by interval. This can cause multiple appends of newInterval.Step 2: Identify duplicate insertion
Because newInterval is appended inside the loop multiple times, duplicates appear in result.Final Answer:
Appending newInterval multiple times causes duplicates -> Option AQuick Check:
Multiple appends = duplicates [OK]
- Appending inside loop multiple times
- Not updating newInterval boundaries
- Forgetting to return result
Solution
Step 1: Merge [2,7] with overlapping intervals
[2,7] overlaps with [1,3] and [6,9]. Merge all three intervals into one covering from min start 1 to max end 9.Step 2: Final merged interval
The merged interval is [1,9], replacing the original two intervals.Final Answer:
[[1,9]] -> Option BQuick Check:
Merge all overlapping = [[1,9]] [OK]
- Partial merges leaving overlaps
- Appending without merging
- Incorrect interval boundaries
Ready to prove it?
Pass the test and this pattern moves unknown
