题目:将数据流变为多个不相交区间
题目描述
给你一个由非负整数 a1, a2, …, an 组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。
实现 SummaryRanges 类:
SummaryRanges() 使用一个空数据流初始化对象。
void addNum(int val) 向数据流中加入整数 val 。
int[][] getIntervals() 以不相交区间 [starti, endi] 的列表形式返回对数据流中整数的总结。
解题思路
首先定义一个区间的数据结构,题解中使用了map来存放区间,当有一个新的值val时,考虑五种情况:
- val包含在某一个区间内
- val可以作为一个区间的右边界
- val可以作为一个区间的左边界
- val可以将两个区间连接起来
- val不属于任何区间
代码
class SummaryRanges {
public:
SummaryRanges() {
}
void addNum(int val) {
// 找第一个比val大的数,按照key来比较
auto l1=arr.upper_bound(val);
// 找最后一个比val小的数,其实就是l1的上一个,但是要考虑l1为begin()时
auto l0=l1==arr.begin()?arr.end():prev(l1);
// 情况1
if(l0!=arr.end()&&l0->first<=val&&l0->second>=val)
return;
else
{
bool left=(l1!=arr.end()&&(l1->first-1==val));
bool right=(l0!=arr.end()&&(l0->second+1==val));
// 情况4
if(left&&right)
{
l0->second=l1->second;
arr.erase(l1);
}
// 情况3
else if(left)
{
int r=l1->second;
arr.erase(l1);
arr.emplace(val,r);
}
// 情况2
else if(right)
{
l0->second=val;
}
// 情况5
else
{
arr.emplace(val,val);
}
}
}
vector<vector<int>> getIntervals() {
vector<vector<int>> ans;
for(const auto& [l,r]:arr) // c++17读取map中数据的方式
{
ans.push_back({l,r});
}
return ans;
}
private:
map<int,int> arr;
};