[LeetCode] Insert Interval

简介: By far the best solution I have seen is of O(n) time (some solutions claim to be of O(logn) turns out to be O(n)).

By far the best solution I have seen is of O(n) time (some solutions claim to be of O(logn) turns out to be O(n)). One of the simplest ideas is to compare each interval in intervals (intervals[i]) with newInterval and then perform respective operations according to their relationships.

  1. If they overlap, merge them to newInterval;
  2. If intervals[i] is to the left of newInterval, push intervals[i] to the result vector;
  3. If newInterval is to the left of intervals[i], push newInterval and all the remaining intervals (intervals[i], ..., intervals[n - 1]) to the result vector.

The code is as follows.

 1 class Solution {
 2 public:
 3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
 4         vector<Interval> res;
 5         int n = intervals.size();
 6         for (int i = 0; i < n; i++) {
 7             if (intervals[i].end < newInterval.start)
 8                 res.push_back(intervals[i]);
 9             else if (newInterval.end < intervals[i].start) {
10                 res.push_back(newInterval);
11                 for (int j = i; j < n; j++)
12                     res.push_back(intervals[j]);
13                 return res;
14             }
15             else newInterval = merge(intervals[i], newInterval);
16         }
17         res.push_back(newInterval);
18         return res;
19     }
20 private:
21     Interval merge(Interval interval1, Interval interval2) {
22         int start = min(interval1.start, interval2.start);
23         int end = max(interval1.end, interval2.end);
24         return Interval(start, end);
25     }
26 };

Another idea is to search for the two ends of the overlapping intervals using binary search. Then we only need to merge newInterval with the intervals at the two ends if they overlap. All the intervals within the two ends will be contained in newInterval.

Let's do an example in the problem statement: intervals = [1, 2], [3, 5], [6, 7], [8, 10], [12, 16] and newInterval = [4, 9]. We first find the rightmost interval with start smaller than that of newInterval, which is [3, 5]. Then we find the leftmost interval with end larger than that of newInterval, which is [8, 10]. Then all the intervals between them will be contained within newInterval (you may check this to convince yourself) and so can be safely ignored. We only need to check whether newInterval overlaps with the two intervals on the two ends and merge them if necessary.

The complete code is as follows.

 1 class Solution {
 2 public:
 3     vector<Interval> insert(vector<Interval>& intervals, Interval newInterval) {
 4         int n = intervals.size(), leftEnd, rightEnd, l, r;
 5         vector<Interval> res;
 6         // Find the rightmost interval with start smaller than that of newInterval
 7         for (l = 0, r = n - 1; l <= r; ) {
 8             int mid = l + ((r - l) >> 1);
 9             if (intervals[mid].start > newInterval.start)
10                 r = mid - 1;
11             else l = mid + 1;
12         }
13         leftEnd = r;
14         // Find the leftmost interval with end larger than that of newInterval
15         for (l = 0, r = n - 1; l <= r; ) {
16             int mid = l + ((r - l) >> 1);
17             if (intervals[mid].end < newInterval.end)
18                 l = mid + 1;
19             else r = mid - 1;
20         }
21         rightEnd = l;
22         // Merge newInterval with intervals[leftEnd] and intervals[rightEnd] if necessary
23         if (leftEnd >= 0 && intervals[leftEnd].end >= newInterval.start)
24             newInterval.start = intervals[leftEnd--].start;
25         if (rightEnd < n && intervals[rightEnd].start <= newInterval.end)
26             newInterval.end = intervals[rightEnd++].end;
27         // Save the intervals sequentially
28         for (int i = 0; i <= leftEnd; i++)
29             res.push_back(intervals[i]);
30         res.push_back(newInterval);
31         for (int i = rightEnd; i < n; i++)
32             res.push_back(intervals[i]);
33         return res;
34     }
35 };

 

目录
相关文章
|
JavaScript 索引
LeetCode 436. Find Right Interval
Given a set of intervals, for each of the interval i, check if there exists an interval j whose start point is bigger than or equal to the end point of the interval i, which can be called that j is on the "right" of i.
58 0
LeetCode 436. Find Right Interval
|
存储 索引
LeetCode 381. Insert Delete GetRandom O1 Dallowed
设计一个支持在平均 时间复杂度 O(1) 下, 执行以下操作的数据结构。
57 0
LeetCode 381. Insert Delete GetRandom O1 Dallowed
|
存储 索引
LeetCode 380. Insert Delete GetRandom O1
设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。
35 0
LeetCode 380. Insert Delete GetRandom O1
LeetCode之Search Insert Position
LeetCode之Search Insert Position
81 0
|
存储 算法 Java
LeetCode 380: 常数时间插入、删除和获取随机元素 Insert Delete GetRandom O(1)
题目: 设计一个支持在平均 时间复杂度 O(1) 下,执行以下操作的数据结构。 insert(val):当元素 val 不存在时,向集合中插入该项。 remove(val):元素 val 存在时,从集合中移除该项。
1041 0