[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.
- If they overlap, merge them to newInterval;
- If intervals[i] is to the left of newInterval, push intervals[i] to the result vector;
- 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 };
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 电商平台中订单未支付过期如何实现自动关单?
· 用 .NET NativeAOT 构建完全 distroless 的静态链接应用
· 为什么构造函数需要尽可能的简单
· 探秘 MySQL 索引底层原理,解锁数据库优化的关键密码(下)
· 大模型 Token 究竟是啥:图解大模型Token
· 1.net core 工作流WorkFlow流程(介绍)
· 瞧瞧别人家的限流,那叫一个优雅!
· 一文彻底搞懂 MCP:AI 大模型的标准化工具箱
· 面试官:如果某个业务量突然提升100倍QPS你会怎么做?
· .NET 平台上的开源模型训练与推理进展