zoukankan      html  css  js  c++  java
  • [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)). 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 };
  • 相关阅读:
    数据结构(树链剖分):NOI2014 购票
    数据结构(树链剖分):COGS 2109. [NOIP2015] 运输计划
    数据结构(树链剖分,堆):HNOI 2016 network
    快速傅里叶变换(FFT):COGS 2216. 你猜是不是KMP
    生成树的计数(基尔霍夫矩阵):BZOJ 1002 [FJOI2007]轮状病毒
    数据结构(线段树):BZOJ 3126: [Usaco2013 Open]Photo
    数位DP:SPOJ KPSUM
    动态规划(状态压缩):BZOJ 2621 [Usaco2012 Mar]Cows in a Skyscraper
    数据结构(并查集):COGS 260. [NOI2002] 银河英雄传说
    生成树的计数(基尔霍夫矩阵):UVAoj 10766 Organising the Organisation SPOJ HIGH
  • 原文地址:https://www.cnblogs.com/jcliBlogger/p/4625034.html
Copyright © 2011-2022 走看看