Non Overlapping Intervals Minimum Removal in DSA Rust - Time & Space Complexity
We want to find out how long it takes to decide the minimum number of intervals to remove so none overlap.
How does the time needed grow as the number of intervals grows?
Analyze the time complexity of the following code snippet.
fn erase_overlap_intervals(intervals: &mut Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.1);
let mut count = 0;
let mut end = std::i32::MIN;
for &(start, finish) in intervals.iter() {
if start >= end {
end = finish;
} else {
count += 1;
}
}
count
}
This code sorts intervals by their end time, then counts how many must be removed to avoid overlaps.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Sorting the intervals and then looping through them once.
- How many times: Sorting takes multiple comparisons (depends on n log n), loop runs once for each interval (n times).
Sorting grows faster than just looping, so it dominates the time.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 * log(10) ≈ 33 operations for sorting + 10 for loop |
| 100 | About 100 * log(100) ≈ 664 operations for sorting + 100 for loop |
| 1000 | About 1000 * log(1000) ≈ 9965 operations for sorting + 1000 for loop |
Pattern observation: As input grows, sorting cost grows faster than the loop, roughly n log n times.
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 loop adds only a little extra.
[X] Wrong: "The loop alone decides the time complexity, so it is O(n)."
[OK] Correct: Sorting the intervals first takes more time than the loop, so it controls the total time needed.
Understanding how sorting affects time helps you explain your solution clearly and shows you know what part of your code costs the most time.
"What if the intervals were already sorted by their start time? How would the time complexity change?"
Practice
Non Overlapping Intervals Minimum Removal problem?Solution
Step 1: Understand the problem goal
The problem asks to remove as few intervals as possible so that no two intervals overlap.Step 2: Clarify what non-overlapping means
Non-overlapping means intervals do not share any common points except possibly touching ends.Final Answer:
To remove the minimum number of intervals so that the remaining intervals do not overlap -> Option CQuick Check:
Minimum removal = non-overlapping intervals [OK]
- Thinking the goal is to merge intervals
- Confusing maximum overlap with minimum removal
- Sorting intervals without removing any
Solution
Step 1: Identify correct vector syntax in Rust
Vectors usevec![]macro with parentheses for tuples.Step 2: Check tuple and vector syntax
let intervals = vec![(1, 3), (2, 4), (3, 5)]; usesvec![(1, 3), (2, 4), (3, 5)]which is correct for vector of tuples.Final Answer:
let intervals = vec![(1, 3), (2, 4), (3, 5)]; -> Option DQuick Check:
vec! macro + tuples = correct syntax [OK]
- Using square brackets for tuples
- Using braces {} instead of brackets [] for vec!
- Declaring array without vec! macro
fn erase_overlap_intervals(mut intervals: Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.1);
let mut count = 0;
let mut end = std::i32::MIN;
for interval in intervals {
if interval.0 >= end {
end = interval.1;
} else {
count += 1;
}
}
count
}
fn main() {
let intervals = vec![(1, 2), (2, 3), (3, 4), (1, 3)];
println!("{}", erase_overlap_intervals(intervals));
}Solution
Step 1: Sort intervals by end time
Sorted intervals: (1,2), (2,3), (1,3), (3,4)Step 2: Iterate and count overlaps
Check intervals: - (1,2): end = 2, count=0 - (2,3): start 2 >= end 2, end=3, count=0 - (1,3): start 1 < end 3, count=1 (remove this) - (3,4): start 3 >= end 3, end=4, count=1Final Answer:
1 -> Option BQuick Check:
One interval removed to avoid overlap [OK]
- Not sorting intervals by end time
- Counting intervals incorrectly when start equals end
- Confusing count of removals with count of intervals
fn erase_overlap_intervals(mut intervals: Vec<(i32, i32)>) -> i32 {
intervals.sort_by_key(|k| k.0);
let mut count = 0;
let mut end = std::i32::MIN;
for interval in intervals {
if interval.0 >= end {
end = interval.1;
} else {
count += 1;
}
}
count
}Solution
Step 1: Check sorting criteria
The function sorts intervals by start time, but correct approach is sorting by end time to minimize removals.Step 2: Understand impact of sorting
Sorting by start time can cause wrong intervals to be kept, increasing removals incorrectly.Final Answer:
Sorting intervals by start time instead of end time causes incorrect removal count -> Option AQuick Check:
Sort by end time, not start time [OK]
- Sorting by start time instead of end time
- Misinitializing end variable
- Returning wrong data type
[(1, 5), (2, 3), (4, 6), (7, 8), (5, 7)], what is the minimum number of intervals to remove to make the rest non-overlapping?Solution
Step 1: Sort intervals by end time
Sorted intervals: (2,3), (1,5), (4,6), (5,7), (7,8)Step 2: Greedily select non-overlapping intervals and count removals
Initialize end = MIN, count = 0- (2,3): 2 >= MIN, keep, end=3
- (1,5): 1 < 3, remove, count=1
- (4,6): 4 >= 3, keep, end=6
- (5,7): 5 < 6, remove, count=2
- (7,8): 7 >= 6, keep, end=8
Final Answer:
2 -> Option AQuick Check:
Minimum removals = 2 [OK]
- Assuming zero removals without checking overlaps
- Not sorting intervals before processing
- Counting removals incorrectly when intervals touch
Ready to prove it?
Pass the test and this pattern moves unknown
