Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1024. Video Stitching - Leetcode Solution

Code Implementation

class Solution:
    def videoStitching(self, clips, time):
        clips.sort()
        res = 0
        curr_end = 0
        next_end = 0
        i = 0
        n = len(clips)
        while curr_end < time:
            while i < n and clips[i][0] <= curr_end:
                next_end = max(next_end, clips[i][1])
                i += 1
            if curr_end == next_end:
                return -1
            res += 1
            curr_end = next_end
        return res
      
class Solution {
public:
    int videoStitching(vector<vector<int>>& clips, int time) {
        sort(clips.begin(), clips.end());
        int res = 0, curr_end = 0, next_end = 0, i = 0, n = clips.size();
        while (curr_end < time) {
            while (i < n && clips[i][0] <= curr_end) {
                next_end = max(next_end, clips[i][1]);
                i++;
            }
            if (curr_end == next_end) return -1;
            res++;
            curr_end = next_end;
        }
        return res;
    }
};
      
import java.util.*;
class Solution {
    public int videoStitching(int[][] clips, int time) {
        Arrays.sort(clips, (a, b) -> a[0] - b[0]);
        int res = 0, curr_end = 0, next_end = 0, i = 0, n = clips.length;
        while (curr_end < time) {
            while (i < n && clips[i][0] <= curr_end) {
                next_end = Math.max(next_end, clips[i][1]);
                i++;
            }
            if (curr_end == next_end) return -1;
            res++;
            curr_end = next_end;
        }
        return res;
    }
}
      
var videoStitching = function(clips, time) {
    clips.sort((a, b) => a[0] - b[0]);
    let res = 0, curr_end = 0, next_end = 0, i = 0, n = clips.length;
    while (curr_end < time) {
        while (i < n && clips[i][0] <= curr_end) {
            next_end = Math.max(next_end, clips[i][1]);
            i++;
        }
        if (curr_end === next_end) return -1;
        res++;
        curr_end = next_end;
    }
    return res;
};
      

Problem Description

You are given a list of video clips, each represented as a pair [start, end], where start and end are integers indicating the start and end times (in seconds) of that clip. You are also given an integer time representing the total duration of the event you want to cover (from 0 to time seconds, inclusive of 0 but exclusive of time).

Your task is to determine the minimum number of clips needed to cover the interval [0, time) entirely. If it is impossible to cover the entire interval, return -1.

Constraints:
  • You can use any clip any number of times (no need to worry about reusing elements).
  • There may be overlap between clips.
  • Each clip is an interval [start, end] with 0 <= start < end <= 100.
  • The number of clips is between 1 and 100.
  • There is no guarantee that a solution exists.

Thought Process

To solve this problem, the first idea that might come to mind is to try every possible combination of clips to see which covers the whole interval using the fewest clips. However, this is not practical because the number of combinations grows exponentially with the number of clips.

Instead, we notice that this problem is similar to the classic "interval covering" or "jump game" problems. Our goal is to always pick the next clip that extends our coverage as far as possible. This greedy approach is efficient and works because, at each step, we want to maximize our progress towards covering the interval. By always choosing the clip that extends coverage the most, we minimize the number of clips used.

The main challenge is handling overlapping intervals and ensuring we never leave a gap in coverage. If we ever reach a point where no clip can extend our coverage, we know it's impossible to cover the interval.

Solution Approach

We use a greedy algorithm to solve the problem efficiently. Here is the step-by-step approach:
  1. Sort the Clips: First, sort the clips array by their start time. This allows us to process them in order and makes it easier to find which clips can extend the current coverage.
  2. Initialize Variables:
    • curr_end: The end of the interval we've currently covered.
    • next_end: The furthest point we can reach from the current position using available clips.
    • res: The count of clips used so far.
    • i: Index to iterate through the sorted clips.
  3. Main Loop: While curr_end is less than time:
    • For all clips that start at or before curr_end, update next_end to the maximum of their end values. This finds the best possible extension from the current coverage.
    • If next_end does not advance beyond curr_end, it means there is a gap and it's impossible to cover the interval. Return -1.
    • Otherwise, increment the clip count (res) and set curr_end to next_end.
  4. Return the Result: Once the loop ends, return res as the minimum number of clips needed.
Justification: This greedy approach works because, at each step, we always select the clip that gives us the farthest reach, ensuring the fewest transitions and no gaps in coverage.

Example Walkthrough

Example Input:
clips = [[0,2],[4,6],[8,10],[1,9],[1,5],[5,9]], time = 10

Step-by-step:
  1. Sort the clips: [[0,2],[1,5],[1,9],[4,6],[5,9],[8,10]]
  2. Start with curr_end = 0, next_end = 0, res = 0, i = 0
  3. First iteration:
    • Clip [0,2] starts at 0, so update next_end = 2 (i=1).
    • No more clips with start ≤ 0. Since next_end > curr_end, increment res = 1, set curr_end = 2.
  4. Second iteration:
    • Clips [1,5] and [1,9] both start ≤ 2. Update next_end to 9 (max of 5 and 9). (i=3)
    • No more clips with start ≤ 2. Increment res = 2, set curr_end = 9.
  5. Third iteration:
    • Clips [4,6], [5,9] start ≤ 9. Update next_end to 9 (no further extension here). (i=5)
    • Clip [8,10] starts ≤ 9. Update next_end to 10. (i=6)
    • Increment res = 3, set curr_end = 10.
  6. curr_end is now 10, so the interval is covered. The answer is 3.

Time and Space Complexity

  • Brute-force approach:
    • Would involve trying all possible combinations of clips, which is exponential time: O(2^N), where N is the number of clips.
    • Space complexity would also be high due to recursion or storing all subsets.
  • Optimized greedy approach (current solution):
    • Sorting the clips takes O(N log N).
    • The main loop iterates over the clips at most once: O(N).
    • Total time complexity: O(N log N).
    • Space complexity is O(1) (ignoring the space used to store the input).

Summary

The Video Stitching problem is an interval covering problem where you must select the minimum number of overlapping clips to cover an entire interval. The elegant greedy solution sorts the clips and always picks the one that extends coverage the farthest at each step, ensuring minimal transitions and no gaps. This approach is both efficient and easy to implement, with a time complexity of O(N log N). The key insight is to maximize coverage at every step, which guarantees the optimal result for this class of problems.