Bird
Raised Fist0
DSA Rustprogramming~5 mins

Merge Overlapping Intervals in DSA Rust - Time & Space Complexity

Choose your learning style10 modes available
Time Complexity: Merge Overlapping Intervals
O(n log n)
Understanding Time Complexity

We want to understand how the time needed to merge overlapping intervals changes as the number of intervals grows.

Specifically, how does the program's work increase when we have more intervals to merge?

Scenario Under Consideration

Analyze the time complexity of the following code snippet.


fn merge_intervals(mut intervals: Vec<(i32, i32)>) -> Vec<(i32, i32)> {
    intervals.sort_by_key(|k| k.0);
    let mut merged = Vec::new();
    for interval in intervals {
        if merged.is_empty() || merged.last().unwrap().1 < interval.0 {
            merged.push(interval);
        } else {
            let last = merged.last_mut().unwrap();
            if last.1 < interval.1 {
                last.1 = interval.1;
            }
        }
    }
    merged
}
    

This code sorts intervals by their start time, then merges any that overlap into one combined interval.

Identify Repeating Operations
  • Primary operation: Sorting the list of intervals by start time.
  • How many times: Sorting takes multiple comparisons, roughly proportional to n log n where n is the number of intervals.
  • Secondary operation: One loop through all intervals to merge them.
  • How many times: This loop runs exactly n times, once per interval.
How Execution Grows With Input

As the number of intervals grows, the sorting step grows faster than the merging loop.

Input Size (n)Approx. Operations
10About 10 * log(10) + 10 = 43 operations
100About 100 * log(100) + 100 = 700 operations
1000About 1000 * log(1000) + 1000 = 10,000 operations

Pattern observation: The sorting dominates and grows faster than just the number of intervals, roughly like n times log n.

Final Time Complexity

Time Complexity: O(n log n)

This means the time needed grows a bit faster than the number of intervals because sorting takes more work as the list grows.

Common Mistake

[X] Wrong: "Merging intervals is just a simple loop, so it must be O(n)."

[OK] Correct: The sorting step before merging takes more time than the loop, so the overall time is not just O(n) but O(n log n).

Interview Connect

Understanding this time complexity helps you explain why sorting is necessary before merging and shows you can analyze combined steps clearly.

Self-Check

"What if the intervals were already sorted? How would the time complexity change?"

Practice

(1/5)
1. What is the main goal when merging overlapping intervals in a list like [[1,3],[2,6],[8,10]]?
easy
A. Remove all intervals that overlap
B. Sort intervals by their end values only
C. Combine intervals that overlap into one continuous interval
D. Split intervals into smaller parts

Solution

  1. Step 1: Understand overlapping intervals

    Intervals overlap if one starts before the other ends. For example, [1,3] and [2,6] overlap.
  2. Step 2: Merge overlapping intervals

    We combine overlapping intervals into one that covers both, like merging [1,3] and [2,6] into [1,6].
  3. Final Answer:

    Combine intervals that overlap into one continuous interval -> Option C
  4. Quick Check:

    Merging overlapping intervals means combining them [OK]
Hint: Merge intervals by combining overlapping ranges [OK]
Common Mistakes:
  • Sorting only by end values misses correct merges
  • Removing intervals instead of merging
  • Splitting intervals unnecessarily
2. Which Rust code snippet correctly sorts a vector of intervals by their start value before merging?
easy
A. intervals.sort_by_key(|interval| interval[0]);
B. intervals.sort();
C. intervals.sort_by(|a, b| b[0].cmp(&a[0]));
D. intervals.sort_by_key(|interval| interval[1]);

Solution

  1. Step 1: Identify sorting by start value

    We want to sort intervals by their first element (start), so we use sort_by_key with interval[0].
  2. Step 2: Check sorting direction and key

    intervals.sort_by_key(|interval| interval[0]); sorts ascending by start, which is correct. intervals.sort_by(|a, b| b[0].cmp(&a[0])); sorts descending, which is wrong. intervals.sort_by_key(|interval| interval[1]); sorts by end, not start.
  3. Final Answer:

    intervals.sort_by_key(|interval| interval[0]); -> Option A
  4. Quick Check:

    Sort by start value using sort_by_key(interval[0]) [OK]
Hint: Use sort_by_key with interval[0] to sort by start [OK]
Common Mistakes:
  • Sorting by end instead of start
  • Sorting descending instead of ascending
  • Using sort() without key for nested vectors
3. What is the output of this Rust code that merges overlapping intervals?
let mut intervals = vec![vec![1,4], vec![2,5], vec![7,9]];
intervals.sort_by_key(|x| x[0]);
let mut merged = vec![];
for interval in intervals {
    if merged.is_empty() || merged.last().unwrap()[1] < interval[0] {
        merged.push(interval);
    } else {
        let last = merged.last_mut().unwrap();
        last[1] = last[1].max(interval[1]);
    }
}
println!("{:?}", merged);
medium
A. [[2,5], [7,9]]
B. [[1,4], [2,5], [7,9]]
C. [[1,9]]
D. [[1,5], [7,9]]

Solution

  1. Step 1: Sort intervals by start

    Sorted intervals: [[1,4], [2,5], [7,9]] (already sorted).
  2. Step 2: Merge overlapping intervals

    [1,4] and [2,5] overlap, merged to [1,5]. [7,9] does not overlap, so added as is.
  3. Final Answer:

    [[1,5], [7,9]] -> Option D
  4. Quick Check:

    Merged intervals = [[1,5], [7,9]] [OK]
Hint: Merge intervals by extending end if overlapping [OK]
Common Mistakes:
  • Not merging overlapping intervals
  • Merging non-overlapping intervals
  • Incorrectly updating interval ends
4. Identify the bug in this Rust code for merging intervals:
let mut intervals = vec![vec![1,3], vec![2,4], vec![5,7]];
intervals.sort_by_key(|x| x[1]);
let mut merged = vec![];
for interval in intervals {
    if merged.is_empty() || merged.last().unwrap()[1] < interval[0] {
        merged.push(interval);
    } else {
        let last = merged.last_mut().unwrap();
        last[1] = last[1].max(interval[1]);
    }
}
println!("{:?}", merged);
medium
A. Sorting by end value causes incorrect merging
B. Using last_mut() causes a runtime error
C. The vector intervals is not mutable
D. The condition to check overlap is reversed

Solution

  1. Step 1: Check sorting key

    The code sorts intervals by their end value, but merging requires sorting by start value to process intervals in order.
  2. Step 2: Effect of wrong sorting

    Sorting by end causes intervals to be processed out of order, leading to missed merges or incorrect merges.
  3. Final Answer:

    Sorting by end value causes incorrect merging -> Option A
  4. Quick Check:

    Sort by start, not end, for correct merging [OK]
Hint: Always sort intervals by start before merging [OK]
Common Mistakes:
  • Sorting by end instead of start
  • Misusing mutable references
  • Incorrect overlap condition
5. Given a list of intervals [[1,3],[2,4],[5,7],[6,8],[9,10]], write a Rust function to merge all overlapping intervals and return the merged list. What is the correct merged output?
hard
A. [[1,3],[2,4],[5,7],[6,8],[9,10]]
B. [[1,4],[5,8],[9,10]]
C. [[1,8],[9,10]]
D. [[1,4],[5,7],[6,8],[9,10]]

Solution

  1. Step 1: Sort intervals by start

    Sorted intervals: [[1,3],[2,4],[5,7],[6,8],[9,10]] (already sorted).
  2. Step 2: Merge overlapping intervals step-by-step

    Merge [1,3] and [2,4] to [1,4]. Merge [5,7] and [6,8] to [5,8]. [9,10] stays separate.
  3. Final Answer:

    [[1,4],[5,8],[9,10]] -> Option B
  4. Quick Check:

    Merge intervals by extending ends where overlapping [OK]
Hint: Merge intervals by sorting and extending ends [OK]
Common Mistakes:
  • Not merging all overlapping intervals
  • Merging non-overlapping intervals
  • Incorrect final intervals after merge
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard