Merge Overlapping Intervals in DSA C# - Time & Space Complexity
We want to understand how the time needed to merge overlapping intervals changes as the number of intervals grows.
How does the program's work increase when we add more intervals?
Analyze the time complexity of the following code snippet.
public int[][] Merge(int[][] intervals) {
Array.Sort(intervals, (a, b) => a[0].CompareTo(b[0]));
List merged = new List();
foreach (var interval in intervals) {
if (merged.Count == 0 || merged[merged.Count - 1][1] < interval[0]) {
merged.Add(interval);
} else {
merged[merged.Count - 1][1] = Math.Max(merged[merged.Count - 1][1], interval[1]);
}
}
return merged.ToArray();
}
This code sorts intervals by start time, then merges overlapping ones into a new list.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting the intervals and then looping through each interval once.
- How many times: Sorting takes multiple comparisons (depends on number of intervals), then the loop runs once per interval.
Sorting grows faster than just looping, so it dominates the time.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 log 10 (sorting) + 10 (loop) |
| 100 | About 100 log 100 + 100 |
| 1000 | About 1000 log 1000 + 1000 |
Pattern observation: As input grows, sorting cost grows faster than the simple loop, so total time grows roughly like n times log n.
Time Complexity: O(n log n)
This means the time to merge intervals grows a bit faster than just the number of intervals, mainly because of sorting.
[X] Wrong: "The merging loop alone decides the time, so it is O(n)."
[OK] Correct: Sorting the intervals first takes more time than the loop, so the total time is not just O(n), but O(n log n).
Understanding how sorting affects the overall time helps you explain your solution clearly and shows you know what part of your code costs the most.
"What if the intervals were already sorted? How would the time complexity change?"
Practice
Merge Overlapping Intervals algorithm?Solution
Step 1: Understand the problem goal
The algorithm aims to merge intervals that share common parts so they become one continuous interval.Step 2: Identify the correct purpose
Among the options, only combining overlapping intervals matches the goal.Final Answer:
To combine all intervals that overlap into a single continuous interval -> Option CQuick Check:
Merge overlapping intervals = combine overlaps [OK]
- Confusing merging with sorting
- Thinking it splits intervals instead of combining
- Assuming it counts intervals
Solution
Step 1: Identify sorting by start time
We need to sort intervals by their start property in ascending order.Step 2: Check each option
intervals.Sort((a, b) => a.Start.CompareTo(b.Start)); uses Sort with CompareTo on Start ascending, which is correct. Others sort by end descending, start descending, or length, which are incorrect for merging.Final Answer:
intervals.Sort((a, b) => a.Start.CompareTo(b.Start)); -> Option DQuick Check:
Sort by start ascending = intervals.Sort((a, b) => a.Start.CompareTo(b.Start)); [OK]
- Sorting by end time instead of start
- Sorting descending instead of ascending
- Sorting by interval length
var intervals = new List<(int Start, int End)>{ (1,3), (2,6), (8,10), (15,18) };
intervals.Sort((a,b) => a.Start.CompareTo(b.Start));
var merged = new List<(int, int)>();
foreach(var interval in intervals) {
if(merged.Count == 0 || merged[^1].End < interval.Start) {
merged.Add(interval);
} else {
var last = merged[^1];
merged[^1] = (last.Start, Math.Max(last.End, interval.End));
}
}
foreach(var i in merged) Console.Write($"({i.Start},{i.End}) ");Solution
Step 1: Sort intervals by start
Sorted intervals: (1,3), (2,6), (8,10), (15,18)Step 2: Merge overlapping intervals
(1,3) and (2,6) overlap, merged to (1,6). Others do not overlap, so final merged list is (1,6), (8,10), (15,18).Final Answer:
(1,6) (8,10) (15,18) -> Option AQuick Check:
Merged intervals = (1,6) (8,10) (15,18) [OK]
- Not merging overlapping intervals
- Merging intervals incorrectly by extending start
- Printing original intervals without merging
var intervals = new List<(int Start, int End)>{ (1,4), (4,5) };
intervals.Sort((a,b) => a.Start.CompareTo(b.Start));
var merged = new List<(int, int)>();
foreach(var interval in intervals) {
if(merged.Count == 0 || merged[^1].End <= interval.Start) {
merged.Add(interval);
} else {
var last = merged[^1];
merged[^1] = (last.Start, Math.Max(last.End, interval.End));
}
}
foreach(var i in merged) Console.Write($"({i.Start},{i.End}) ");Solution
Step 1: Analyze the merge condition
The condition uses merged[^1].End <= interval.Start, which treats touching intervals as non-overlapping.Step 2: Identify correct condition for merging
To merge intervals that touch (like (1,4) and (4,5)), use < instead of <= so they merge into (1,5).Final Answer:
The condition should use < instead of <= to merge touching intervals -> Option AQuick Check:
Use < to merge touching intervals [OK]
- Using <= causes touching intervals to not merge
- Forgetting to sort intervals
- Ignoring empty input cases
[(1,5), (2,3), (4,8), (10,12), (9,10)], what is the merged list after applying the merge overlapping intervals algorithm?Solution
Step 1: Sort intervals by start
Sorted intervals: (1,5), (2,3), (4,8), (9,10), (10,12)Step 2: Merge overlapping intervals step-by-step
Merge (1,5) and (2,3) -> (1,5); merge (1,5) and (4,8) -> (1,8); merge (9,10) and (10,12) -> (9,12). Final merged intervals: (1,8), (9,12).Final Answer:
[(1,8), (9,12)] -> Option BQuick Check:
Merged intervals = [(1,8), (9,12)] [OK]
- Not merging intervals that overlap inside others
- Missing to merge touching intervals
- Returning original intervals without merging
Ready to prove it?
Pass the test and this pattern moves unknown
