[leetcode]352. Data Stream as Disjoint Intervals

本文介绍了一种算法问题,即如何从连续输入的数据流中总结出一系列不相交的区间。通过对每个新输入数字的处理,文章详细解释了两种实现方法:一种是基于向量的方法,另一种是使用集合和二分查找的高效方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:https://leetcode.com/problems/data-stream-as-disjoint-intervals/description/

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?

Credits:
Special thanks to @yunhong for adding this problem and creating most of the test cases.


这道题说有个数据流每次提供一个数字,然后让我们组成一系列分离的区间,这道题跟之前那道Insert Interval很像,思路也很像,每进来一个新的数字val,我们都生成一个新的区间[val, val],然后将其插入到当前的区间里,注意分情况讨论,无重叠,相邻,和有重叠分开讨论处理。


方法一:

class SummaryRanges {
public:
    /** Initialize your data structure here. */
    SummaryRanges() {

    }

    void addNum(int val) {
        Interval cur(val,val);
        vector<Interval> res;
        int pos=0;
        for(auto a:v)
        {
            if(cur.end+1<a.start)
                res.push_back(a);
            else if(cur.start>a.end+1)
            {
                res.push_back(a);
                ++pos;
            }
            else
            {
                cur.start=min(cur.start,a.start);
                cur.end=max(cur.end,a.end);
            }
        }
        res.insert(res.begin()+pos,cur);
        v=res;
    }

    vector<Interval> getIntervals() {
        return v;
    }
private:
    vector<Interval> v;
};



方法二:(二分法)

class SummaryRanges {
public:
    /** Initialize your data structure here. */
    SummaryRanges() {

    }

    void addNum(int val) {
        auto it=st.lower_bound(Interval(val,val));
        int start=val,end=val;
        if(it!=st.begin() && (--it)->end+1<val) it++;
        while(it!=st.end() && val+1>=it->start && val-1<=it->end)
        {
            start=min(start,it->start);
            end=max(end,it->end);
            it=st.erase(it);
        }
        st.insert(it,Interval(start,end));
    }

    vector<Interval> getIntervals() {
        vector<Interval> res;
        for(auto val:st) res.push_back(val);
        return res;
    }
private:
    struct Cmp{
        bool operator()(Interval a,Interval b){return a.start<b.start;}
    };
    set<Interval,Cmp> st;
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值