Given a collection of intervals, merge all overlapping intervals.
For example,
Given [1,3],[2,6],[8,10],[15,18],
return [1,6],[8,10],[15,18].
区间合并 和 求最长区间 一样,关键在于如何记录区间信息,能够降低复杂度。
最简单的思路是用一个bool数组,记录区间中的每一位是否被覆盖。
例如:
intervals: [1, 4] [8, 9] [20, 30] [7, 14] [2, 9]
设一个数组 bool f[30],初始化全部为false
[1, 4]就把f[1]..f[4]全部置为true
其他区间一次类推,最后扫描f数组,就能得到区间合并的结果。
这种做法对于小数据还行,大数据会超市。
这样做,存在很多重复工作,例如[1, 4] [8, 9] [7, 14] [2, 9]这四个区间,会反复将f[2] f[3] f[4][ f[5] f[6] f[7] f[8] f[9]设为true。
所以,我们需要考虑的是如何去除重复的工作。实际上,两个端点就能描述出一个区间,关键在于如何标记出两个端点,让我们在扫描时能够知道这个区间被覆盖。
一个很巧妙的做法就是进入一个区间就加1,出一个区间就减1,如果数值大于0,说明当前处于一个区间中。
还是以刚刚的intervals为例。
设数组 int l[30], r[30],初始化全部为0
[1, 4]:l[1]++, r[4]--
[8, 9]:l[8]++, r[9]--
...
扫描时,用一个count记录,每次:
count += l[i],如果count>0说明i处于一个区间中
count -= r[i],如果count==0说明i是一个区间的尾端点
- /**
- * Definition for an interval.
- * struct Interval {
- * int start;
- * int end;
- * Interval() : start(0), end(0) {}
- * Interval(int s, int e) : start(s), end(e) {}
- * };
- */
- class Solution {
- public:
- vector<Interval> merge(vector<Interval> &intervals) {
- // Start typing your C/C++ solution below
- // DO NOT write int main() function
- vector<Interval> answer;
- if (intervals.empty()) {
- return answer;
- }
- int min = 1000000, max = -1000000;
- for (vector<Interval>::iterator iter = intervals.begin(); iter != intervals.end(); iter++) {
- min = min < iter->start ? min : iter->start;
- max = max > iter->end ? max : iter->end;
- }
- int left[max - min + 1];
- int right[max - min + 1];
- memset(left, 0, sizeof(int) * (max - min + 1));
- memset(right, 0, sizeof(int) * (max - min + 1));
- for (vector<Interval>::iterator iter = intervals.begin(); iter != intervals.end(); iter++) {
- left[iter->start - min]++;
- right[iter->end - min]++;
- }
- int start = -1, count = 0;
- for (int i = 0; i < max - min + 1; i++) {
- count += left[i];
- if (count > 0 && start == -1) {
- start = i;
- }
- count -= right[i];
- if (count == 0 && start != -1) {
- answer.push_back(Interval(start + min, i + min));
- start = -1;
- }
- }
- return answer;
- }
-
- };
-
- 如果要在Vector容器中存放结构体类型的变量,经常见到两种存放方式.
-
方式一:放入这个结构体类型变量的副本。
方式二:放入指向这个结构体类型变量的指针。
假设结构体类型变量是这样的,
- typedef struct student{
- char school_name[100];
- char gender;
- int age;
- bool is_absent;
- } StudentInfo;
那么,方式一和方式二的实现分别如下所示:
- /*[方式一] 结构体放栈中,vector中放副本---------------------*/
- #include <iostream>
- #include <string>
- #include <vector>
- typedef struct student{
- char school_name[100];
- char gender;
- int age;
- bool is_absent;
- } StudentInfo;
- typedefstd::vector<StudentInfo> StudentInfoVec;
- void print(StudentInfoVec* stduentinfovec){
- for (int j=0;j<(*stduentinfovec).size();j++)
- {
- std::cout<<
- (*stduentinfovec)[j].school_name<<"\t"<<
- (*stduentinfovec)[j].gender<<"\t"<<
- (*stduentinfovec)[j].age<<"\t"<<
- (*stduentinfovec)[j].is_absent<<"\t"<<std::endl;
- }
- return;
- }
- int main(){
- StudentInfo micheal={"Micheal",'m',18,false};
- StudentInfo cherry={"Cherry",'f',16,true};
- StudentInfoVec studentinfovec;
- studentinfovec.push_back(micheal);
- studentinfovec.push_back(cherry);
- print(&studentinfovec);
- return 0;
- }
- /*[方式二] 结构体放入堆中,vector中放指针---------------------*/
- typedef struct student{
- char* school_name;
- char gender;
- int age;
- bool is_absent;
- } StudentInfo;
- typedefstd::vector<StudentInfo*> StudentInfoPtrVec;
- void print(StudentInfoPtrVec*stduentinfoptrvec){
- for (int j=0;j<(*stduentinfoptrvec).size();j++)
- {
- std::cout<<
- (*stduentinfoptrvec)[j]->school_name<<"\t"<<
- (*stduentinfoptrvec)[j]->gender<<"\t"<<
- (*stduentinfoptrvec)[j]->age<<"\t"<<
- (*stduentinfoptrvec)[j]->is_absent<<"\t"<<std::endl;
- }
- return;
- }
- int main(){
- StudentInfoPtrVec studentinfoptrvec;
- char* p_char_1=NULL;
- p_char_1=new char[100];
- strcpy(p_char_1,"Micheal");
- StudentInfo* p_student_1=new StudentInfo;
- p_student_1->school_name=p_char_1;
- p_student_1->gender='m';
- p_student_1->age=18;
- p_student_1->is_absent=false;
- studentinfoptrvec.push_back(p_student_1);
- char* p_char_2=NULL;
- p_char_2=new char[100];
- strcpy(p_char_2,"Cherry");
- StudentInfo* p_student_2=new StudentInfo;
- p_student_2->school_name=p_char_2;
- p_student_2->gender='f';
- p_student_2->age=16;
- p_student_2->is_absent=false;
- studentinfoptrvec.push_back(p_student_2);
- print(&studentinfoptrvec);
- delete p_char_1;
- delete p_student_1;
- delete p_char_2;
- delete p_student_2;
- return 0;
- }
方式二的输出结果,同上,依然是