跳转至

57. Insert Interval

Leetcode Array Sort

Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary).

You may assume that the intervals were initially sorted according to their start times.

Example 1:

Input: intervals = [[1,3],[6,9]], newInterval = [2,5]
Output: [[1,5],[6,9]]

Example 2:

Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8]
Output: [[1,2],[3,10],[12,16]]
Explanation: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].

分析

插入区间。这道题目是56. Merge Intervals的升级版,其实换汤不换药。把区间插入到正确位置,然后再merge即可。或者直接插入,然后排序,然后再merge。

public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
    // special case: interval is empty
    if (intervals == null || intervals.size() == 0) return Collections.singletonList(newInterval);
    int n = intervals.size();
    // special case: add newInterval to the end of intervals
    if (newInterval.start > intervals.get(n - 1).end) {
        intervals.add(newInterval);
        return intervals;
    }

    // special case: add newInterval to the beginning of intervals
    if (newInterval.end < intervals.get(0).start) {
        intervals.add(0, newInterval);
        return intervals;
    }

    // general case: add newInterval to the middle of intervals;
    int i = 0;
    while (i < n && newInterval.start > intervals.get(i).start) i++;
    intervals.add(i, newInterval);
    return merge(intervals);
}

private List<Interval> merge(List<Interval> intervals) {
    LinkedList<Interval> merged = new LinkedList<>();
    merged.add(intervals.get(0));
    for (Interval interval: intervals.subList(1, intervals.size()))
        if (merged.getLast().end < interval.start) merged.add(interval);
        else if (merged.getLast().end < interval.end) merged.getLast().end = interval.end;
    return merged;
}

最好的办法就是只merge部分区间,

public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
    List<Interval> result = new ArrayList<>();
    int  n = intervals.size(), i = 0;
    // add all the intervals ending before newInterval starts
    while (i < n && intervals.get(i).end < newInterval.start)
        result.add(intervals.get(i++));
    // merge all overlapping intervals to one considering newInterval
    while (i < n && intervals.get(i).start <= newInterval.end) {
        newInterval = new Interval( // we could mutate newInterval here also
                Math.min(newInterval.start, intervals.get(i).start),
                Math.max(newInterval.end, intervals.get(i).end));
        i++;
    }
    result.add(newInterval); // add the union of intervals we got
    // add all the rest
    while (i < n) result.add(intervals.get(i++)); 
    return result;
}