LeetCode 57. 插入区间

题目链接:https://leetcode-cn.com/problems/insert-interval/



解法一:可以LeetCode 56 题的合并区间为基础。   将newInterval插入至intervals中,然后对intervals进行合并区间,就能够得到最终的结果。   时间复杂度:O(N)



解法二:贪心算法。

配合代码讲解:

  • 使用start_ptr和end_ptr记录需要被合并的块区间。
  • 用start_pos和end_pos记录合并的区间的端点值。
  • 使用start_flag来记录是否找到左端点。
  • 使用tmp_ptr遍历intervals,我们将intervals分解成为多个tmp和tmp之前的区域,分别对区间之前的区域和区间进行讨论,还需要对左端点和右端点进行讨论:因此对应4个if,最后得到start_pos,end_pos。
intervals = [[1,3],[6,9]], newInterval = [2,5]
[﹣∞ , 1) , [1 , 3]        (3,6),[6,9]       (9,∞)
  • 初始值很重要!可能存在这种情况,newInterval最后插入在intervals的最后边,不需要进行合并。   在这种情况下,处理过程不会对start_pos,end_pos,start_ptr,end_ptr进行任何的修改,因此,初始值将他们最后需要的值。
 1 vector<vector<int>> insert(vector<vector<int>>& intervals, vector<int>& newInterval) {
 2         if(intervals.empty()){
 3             intervals.push_back(newInterval);
 4             return intervals;
 5         }
 6         auto start_ptr=intervals.end(); //intervals中需要删除的起始块
 7         auto end_ptr=intervals.end(); // [start_ptr,end_ptr);
 8         auto tmp_ptr=intervals.begin();  // 遍历指针
 9         int start_pos=newInterval[0];  // 新插入区间的左端点
10         int end_pos=newInterval[1];  // 右端点
11         bool start_flag=false;  // 左端点判断 ,true:表示左端点已确定
12
13         while(tmp_ptr!=intervals.end()){
14             // 左端点,区间之外,取newInterval[0];
15             if(newInterval[0]<(*tmp_ptr)[0]){
16                 if(!start_flag){
17                     start_pos=newInterval[0];
18                     start_ptr=tmp_ptr;
19                     start_flag=true;
20                 }
21             }
22             // 左端点,区间之内
23             if(newInterval[0]>=(*tmp_ptr)[0] && newInterval[0]<=(*tmp_ptr)[1]){
24                 if(!start_flag){
25                     start_pos=(*tmp_ptr)[0];
26                     start_ptr=tmp_ptr;
27                     start_flag=true;
28                 }
29             }
30             if(newInterval[1]<(*tmp_ptr)[0]){
31                 end_pos=newInterval[1];
32                 end_ptr=tmp_ptr;
33                 break;
34             }
35             if(newInterval[1]<(*tmp_ptr)[1] && newInterval[1]<=(*tmp_ptr)[1]){
36                 end_pos=(*tmp_ptr)[1];
37                 end_ptr=++tmp_ptr;
38                 break;
39             }
40             tmp_ptr++;
41         }
42         start_ptr=intervals.erase(start_ptr,end_ptr);
43         intervals.insert(start_ptr,vector<int>{start_pos,end_pos});
44         return intervals;
45     }

关于容器操作可能使vector迭代器失效:

  • 对于插入元素,如果存储空间重新分配,那么指向容器的迭代器,指针,引用全部失效。如果没有分配,那么插入位置之后的迭代器,指针,引用全部失效。
  • 如果是删除,那么被删元素之前的迭代器,指针,引用全部有效。

对于insert和erase,都能够返回迭代器。

原文地址:https://www.cnblogs.com/yy-1046741080/p/12234270.html

时间: 2024-08-04 16:32:55

LeetCode 57. 插入区间的相关文章

LeetCode --- 57. Insert Interval

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: Given intervals [1,3],[6,9], insert and merge

[LeetCode] 57. Insert Interval 解决思路

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:Given intervals [1,3],[6,9], insert and merge [

算法5-7:区间搜索

区间搜索问题就是给定一系列区间,和一个待测区间,求与待测区间相交的区间. 为了解决这个问题,需要专门编写一个类,这个类的接口如下: public interface IntervalST<Key extends Comparable<Key>, Value> { void put(Key lo, Key hi, Value value); Value get(Key lo, Key hi) void delete(Key lo, Key hi) Iterable<Value&

插入区间--Insert Intervals

https://leetcode.com/problems/insert-interval/ Insert Interval 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 t

算法5-7:区间检索

间隔搜索问题给出了一系列的范围,而测试的时间间隔,寻找和测试间隔交叉间隔. 为了解决问题,须要专门编写一个类,这个类的接口例如以下: public interface IntervalST<Key extends Comparable<Key>, Value> { void put(Key lo, Key hi, Value value); Value get(Key lo, Key hi) void delete(Key lo, Key hi) Iterable<Value

[BZOJ3065]带插入区间K小值 解题报告 替罪羊树+值域线段树

刚了一天的题终于切掉了,数据结构题的代码真**难调,这是我做过的第一道树套树题,做完后感觉对树套树都有阴影了......下面写一下做题记录. Portal Gun:[BZOJ3065]带插入区间k小值. 这道题的题面其实都提醒怎么做了,维护区间k小值用值域线段树,但要维护一个插入操作,树状数组套主席树也用不了,那么这道题还剩下平衡树可以搞,那就上平衡树吧. 我这里的做法,因为要维护序列的顺序,所以我这里用到替罪羊树套值域线段树:我们在替罪羊树的每个节点都套一颗值域线段树,记录以该节点为根的子树的

bzoj 3065: 带插入区间K小值 替罪羊树 &amp;&amp; AC300

3065: 带插入区间K小值 Time Limit: 60 Sec  Memory Limit: 512 MBSubmit: 1062  Solved: 253[Submit][Status] Description 从 前有n只跳蚤排成一行做早操,每只跳蚤都有自己的一个弹跳力a[i].跳蚤国王看着这些跳蚤国欣欣向荣的情景,感到非常高兴.这时跳蚤国王决定理性愉悦一 下,查询区间k小值.他每次向它的随从伏特提出这样的问题: 从左往右第x个到第y个跳蚤中,a[i]第k小的值是多少. 这可难不倒伏特,

插入区间

给出一个无重叠的按照区间起始端点排序的区间列表. 在列表中插入一个新的区间,你要确保列表中的区间仍然有序且不重叠(如果有必要的话,可以合并区间). 样例 插入区间[2, 5] 到 [[1,2], [5,9]],我们得到 [[1,9]]. 插入区间[3, 4] 到 [[1,2], [5,9]],我们得到 [[1,2], [3,4], [5,9]]. 1 /** 2 * Definition of Interval: 3 * public classs Interval { 4 * int star

【BZOJ】3065: 带插入区间K小值

题意:带插入.修改的区间k小值在线查询.(原序列n<=35000, 询问<=175000) #include <bits/stdc++.h> using namespace std; const int nTr=1000005, nSg=15000005, alphaA=4, alphaB=5; int STop; struct Seg *Snull; struct Seg { Seg *l, *r; int s, cnt; }Sg[nSg], *iSg=Sg, *bin[nSg]