Why Intervals Are a Common Problem Pattern in DSA Javascript - Performance Analysis
Intervals problems often involve checking or merging ranges, which requires careful analysis of how many times we process each interval.
We want to understand how the number of intervals affects the work done by the algorithm.
Analyze the time complexity of the following code snippet.
function mergeIntervals(intervals) {
intervals.sort((a, b) => a[0] - b[0]);
const merged = [];
for (const interval of intervals) {
if (!merged.length || merged[merged.length - 1][1] < interval[0]) {
merged.push(interval);
} else {
merged[merged.length - 1][1] = Math.max(merged[merged.length - 1][1], interval[1]);
}
}
return merged;
}
This code merges overlapping intervals by first sorting them and then combining where needed.
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 n log n), then the loop runs once for each interval (n times).
As the number of intervals increases, sorting takes more time, and the merging loop grows linearly.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * log 10 + 10 ≈ 43 operations |
| 100 | About 100 * log 100 + 100 ≈ 700 operations |
| 1000 | About 1000 * log 1000 + 1000 ≈ 10,000 operations |
Pattern observation: The sorting dominates and grows faster than the simple loop, roughly n log n growth.
Time Complexity: O(n log n)
This means the time needed grows a bit faster than the number of intervals because of sorting, but the merging step is just a simple pass.
[X] Wrong: "Merging intervals is always O(n) because we just loop once."
[OK] Correct: Sorting the intervals first takes more time, so the total work is more than just one loop.
Understanding how sorting and looping combine helps you explain your approach clearly and shows you know what makes interval problems tricky.
"What if the intervals were already sorted? How would the time complexity change?"
Practice
Solution
Step 1: Understand what intervals represent
Intervals represent ranges, such as time periods or numeric ranges, which are common in real-world scenarios.Step 2: Connect intervals to problem patterns
Many problems require managing overlapping or merging these ranges, making intervals a common pattern.Final Answer:
Because many real-world problems involve ranges or periods of time -> Option DQuick Check:
Intervals = ranges in real life [OK]
- Assuming intervals are always sorted
- Thinking intervals never overlap
- Believing intervals are single points
Solution
Step 1: Recall JavaScript object syntax
Objects use curly braces with key-value pairs like {key: value}.Step 2: Match the correct interval representation
The interval with start and end keys is correctly written as {start: 1, end: 5}.Final Answer:
const interval = {start: 1, end: 5}; -> Option CQuick Check:
Object syntax = {key: value} [OK]
- Using square brackets for objects
- Using parentheses for objects
- Missing keys in object syntax
const intervals = [
{start: 1, end: 3},
{start: 2, end: 6},
{start: 8, end: 10}
];
const merged = [];
intervals.sort((a, b) => a.start - b.start);
for (const interval of intervals) {
if (!merged.length || merged[merged.length - 1].end < interval.start) {
merged.push(interval);
} else {
merged[merged.length - 1].end = Math.max(merged[merged.length - 1].end, interval.end);
}
}
console.log(merged);Solution
Step 1: Sort intervals by start
Intervals are sorted as [{1,3}, {2,6}, {8,10}].Step 2: Merge overlapping intervals
First interval added. Second overlaps with first, so merge to {1,6}. Third does not overlap, so added as is.Final Answer:
[{start: 1, end: 6}, {start: 8, end: 10}] -> Option AQuick Check:
Merged intervals = [{1,6}, {8,10}] [OK]
- Not sorting intervals before merging
- Overwriting intervals incorrectly
- Missing to merge overlapping intervals
const intervals = [
{start: 1, end: 4},
{start: 3, end: 5}
];
const merged = [];
for (const interval of intervals) {
if (!merged.length || merged[merged.length - 1].end < interval.start) {
merged.push(interval);
} else {
merged[merged.length - 1].end = Math.max(merged[merged.length - 1].end, interval.end);
}
}
console.log(merged);Solution
Step 1: Check if intervals are sorted
The code does not sort intervals before merging, which can cause incorrect merges.Step 2: Understand impact of missing sort
Without sorting, overlapping intervals may not be adjacent, so merging logic fails.Final Answer:
Intervals are not sorted before merging -> Option BQuick Check:
Sort intervals first [OK]
- Forgetting to sort intervals
- Using wrong Math function
- Ignoring overlap checks
Solution
Step 1: Sort intervals by start time
Sorting helps process meetings in chronological order.Step 2: Use a min-heap to track earliest ending meeting
Min-heap stores end times; if a meeting starts after earliest end, reuse room; else add room.Step 3: Count maximum rooms used simultaneously
The heap size at any time shows rooms needed; max size is minimum rooms required.Final Answer:
Sort intervals by start time, use a min-heap to track end times, count max rooms needed -> Option AQuick Check:
Min rooms = max overlapping intervals [OK]
- Merging intervals instead of counting overlaps
- Ignoring meeting end times
- Using stack instead of min-heap
Ready to prove it?
Pass the test and this pattern moves unknown
