Leetcode -

[分析]
这道题思路直接,但bug free需要费些心力。第一版未优化的代码笔记长,未贴。
下面给出的两个实现,实现1是使用二分法找到新区间应插入的位置,然后检查是否需要和上一个区间合并(容易忽略),最后同后面的区间逐个检查是否需要合并。无需额外空间,Code Ganker 指出这种做法严格上非O(N),因为合并时有数组remove操作,最坏情况下是O(N^2),但跑leetcode测试用例这种实现比实现2效率高。
实现2:代码非常简洁,需要使用额外空间。先跳过新区间无交集且在新区间前面的,然后merge 和新区间有交集的,最后加上剩余的。


[ref]
http://blog.csdn.net/linhuanmars/article/details/22238433
http://blog.csdn.net/kenden23/article/details/17264441

/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    // Method 2: 使用额外空间,Time:O(N)
    public List<Interval> insert2(List<Interval> intervals, Interval newInterval) {
        List<Interval> result = new ArrayList<Interval>();
        int i = 0;
        int N = intervals.size();
        while (i < N && newInterval.start > intervals.get(i).end) {
            result.add(intervals.get(i++));
        }
        if (i < N) {
            newInterval.start = Math.min(newInterval.start, intervals.get(i).start);
        }
        while (i < N && newInterval.end >= intervals.get(i).start) {
            newInterval.end = Math.max(newInterval.end, intervals.get(i++).end);
        }
        result.add(newInterval);
        while (i < N) {
            result.add(intervals.get(i++));
        }
        return result;
    }
    // Method 1: 二分法查找插入位置,无额外空间
    public List<Interval> insert(List<Interval> intervals, Interval newInterval) {
        if (intervals == null || intervals.size() == 0) {
            List<Interval> result = new ArrayList<Interval>();
            result.add(newInterval);
            return result;
        }
        int N = intervals.size();
        int i = findInsertPos(intervals, newInterval.start);
        // 判断是否需要和前一个区间merge
        if (i > 0 && intervals.get(i - 1).end >= newInterval.start) {
            newInterval.start = intervals.get(i - 1).start;
            newInterval.end = Math.max(newInterval.end, intervals.get(i - 1).end);
            intervals.remove(--i);
        }
        intervals.add(i, newInterval);
        i++;
        // 合并同newInterval有交集的区间
        while (i < intervals.size() && newInterval.end >= intervals.get(i).start) {
            newInterval.end = Math.max(newInterval.end, intervals.get(i).end);
            intervals.remove(i);
        }
        return intervals;
    }
    public int findInsertPos(List<Interval> intervals, int target) {
        int left = 0, right = intervals.size() - 1;
        int mid = 0;
        while (left <= right) {
            mid = left + ((right - left) >> 1);
            Interval curr = intervals.get(mid);
            if (curr.start == target)
                return mid;
            else if (curr.start > target)
                right = mid - 1;
            else
                left = mid + 1;
        }
        return left;
    }
}

你可能感兴趣的:(LeetCode)