You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
Credits:
Special thanks to @yunhong for adding this problem and creating most of the test cases.
这道题说有个数据流每次提供一个数字,然后让我们组成一系列分离的区间,这道题跟之前那道 Insert Interval 很像,思路也很像,每进来一个新的数字 val,都生成一个新的区间 [val, val],并且新建一个空的区间数组 res,用一个变量 cur 来保存要在现有的区间数组中加入新区间的位置。此时遍历现有的区间数组 intervals,对于每一个遍历到的当前区间 interval,假如要加入的区间的结尾位置加1比当前区间的起始位置小,说明二者不相连,将当前区间加入 res。否则当要加入区间的起始位置大于当前位置的结束位置加1,说明二者也没有交集,可以将当前区间加入 res,不过此时 cur 要自增1,因为要加入区间的位置在当前区间的后面。再否则的话,二者就会有交集,需要合并,此时用二者起始位置中较小的更新要加入区间的起始位置,同理,用二者结束位置中较大的去更新要加入区间的结束位置。最终将要加入区间放在 res 中的 cur 位置,然后将 res 赋值给 intervals 即可,参见代码如下:
Hello, here is my solution to this problem. Because the intervals vector we maintain is sorted, therefore we can search the position where we insert/modify the intervals using dichotomy.
Here's the code.
class SummaryRanges {
public:
vector<vector<int>> intervals;
/** Initialize your data structure here. */
SummaryRanges() {
}
void addNum(int val) {
if(intervals.empty()) intervals.push_back(vector<int>({val, val}));
if(val<intervals[0][0])
{
if(val==intervals[0][0]-1) intervals[0][0] = val;
else intervals.insert(intervals.begin(),vector<int>({val,val}));
}
else if(val>intervals.back()[1])
{
if(val==intervals.back()[1]+1) intervals.back()[1] = val;
else intervals.insert(intervals.end(),vector<int>({val,val}));
}
else if(intervals.back()[0]<=val) return;
else
{
int left = 0;
int right = intervals.size()-1;
while(left<right)
{
int mid = left + (right-left)/2;
if(intervals[mid][0]==val) return;
else if(intervals[mid][0]>val) right = mid;
else left = mid+1;
}
left--;
if(val<=intervals[left][1]) return;
else if(val==intervals[left][1]+1) intervals[left][1] = val;
else
{
intervals.insert(intervals.begin()+left+1, vector<int>({val,val}));
left++;
}
// 看能不能和后面的连上
if(left+1<intervals.size())
{
if(intervals[left+1][0]==val+1)
{
intervals[left][1] = intervals[left+1][1];
intervals.erase(intervals.begin()+left+1);
}
}
}
}
vector<vector<int>> getIntervals() {
return intervals;
}
};
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:
Follow up:
What if there are lots of merges and the number of disjoint intervals are small compared to the data stream's size?
NOTE: input types have been changed on April 15, 2019. Please reset to default code definition to get new method signature.
Credits:
Special thanks to @yunhong for adding this problem and creating most of the test cases.
这道题说有个数据流每次提供一个数字,然后让我们组成一系列分离的区间,这道题跟之前那道 Insert Interval 很像,思路也很像,每进来一个新的数字 val,都生成一个新的区间 [val, val],并且新建一个空的区间数组 res,用一个变量 cur 来保存要在现有的区间数组中加入新区间的位置。此时遍历现有的区间数组 intervals,对于每一个遍历到的当前区间 interval,假如要加入的区间的结尾位置加1比当前区间的起始位置小,说明二者不相连,将当前区间加入 res。否则当要加入区间的起始位置大于当前位置的结束位置加1,说明二者也没有交集,可以将当前区间加入 res,不过此时 cur 要自增1,因为要加入区间的位置在当前区间的后面。再否则的话,二者就会有交集,需要合并,此时用二者起始位置中较小的更新要加入区间的起始位置,同理,用二者结束位置中较大的去更新要加入区间的结束位置。最终将要加入区间放在 res 中的 cur 位置,然后将 res 赋值给 intervals 即可,参见代码如下:
解法一:
感谢热心网友 greentrail 的提醒,我们可以对上面的解法进行优化。由于上面的方法每次添加区间的时候,都要把 res 赋值给 intervals,整个区间数组都要进行拷贝,十分的不高效。这里换一种方式,用一个变量 overlap 来记录所有跟要加入区间有重叠的区间的个数,用变量i表示新区间要加入的位置,这样只要最后 overlap 大于0了,现在 intervals 中将这些重合的区间删掉,然后再将新区间插入,这样就不用进行整体拷贝了,提高了效率,参见代码如下:
解法二:
Github 同步地址:
#352
类似题目:
Insert Interval
Range Module
Find Right Interval
Summary Ranges
参考资料:
https://leetcode.com/problems/data-stream-as-disjoint-intervals/
https://leetcode.com/problems/data-stream-as-disjoint-intervals/discuss/82557/Very-concise-c%2B%2B-solution.
https://leetcode.com/problems/data-stream-as-disjoint-intervals/discuss/82616/C%2B%2B-solution-using-map.-O(logN)-per-adding.
https://leetcode.com/problems/data-stream-as-disjoint-intervals/discuss/82553/Java-solution-using-TreeMap-real-O(logN)-per-adding.
LeetCode All in One 题目讲解汇总(持续更新中...)
The text was updated successfully, but these errors were encountered: