Given a data stream input of non-negative integers a1, a2, ..., an, ..., summarize the numbers seen so far as a list of disjoint intervals.
For example, suppose the integers from the data stream are 1, 3, 7, 2, 6, ..., then the summary will be:
[1, 1] [1, 1], [3, 3] [1, 1], [3, 3], [7, 7] [1, 3], [7, 7] [1, 3], [6, 7]
Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?
这是一个合并区间的问题。如果插入的数是与某区间是相连的或者包含在某区间内,则由这个区间和这个数组成新的区间,比如[1,2]和3组成[1,3],[1,3]和2组成[1,3]。这里用set储存区间,插入区间时用lower_bound选择合适的位置,然后调整两边的区间和得到的区间,最后插入即可。函数getIntervals负责返回结果,要把set转换成vector。
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <set>
using namespace std;
struct Interval {
int start;
int end;
Interval() : start(0), end(0) {}
Interval(int s, int e) : start(s), end(e) {}
};
struct cmp
{
bool operator()(const Interval& i1,const Interval& i2)
{
if(i1.start!=i2.start) return i1.start<i2.start;
else return i1.end<i2.end;
}
};
class SummaryRanges {
public:
/** Initialize your data structure here. */
SummaryRanges() {
}
void addNum(int val) {
Interval itv(val,val);
if(Set.empty())
{
Set.insert(itv);
return;
}
auto lb=Set.lower_bound(itv);
if(lb!=Set.begin())
{
if(prev(lb)->end>=val-1)
{
itv.start=prev(lb)->start;
itv.end=max(itv.end,prev(lb)->end);
Set.erase(prev(lb));
}
}
if(lb!=Set.end())
{
if(lb->start<=val+1)
{
itv.start=min(lb->start,itv.start);
itv.end=lb->end;
Set.erase(lb);
}
}
Set.insert(itv);
}
vector<Interval> getIntervals() {
return vector<Interval>(Set.begin(),Set.end());
}
private:
set<Interval,cmp>Set;
};
void print(SummaryRanges sr)
{
vector<Interval>res=sr.getIntervals();
for(int i=0;i<res.size();i++)
{
cout<<res[i].start<<" "<<res[i].end<<endl;
}
}
int main()
{
SummaryRanges sr;
print(sr);
sr.addNum(1);
sr.addNum(3);
sr.addNum(7);
sr.addNum(2);
sr.addNum(6);
print(sr);
}