【LeetCode】352. 将数据流变为多个不相交间隔 结题报告 (C++)

本文探讨了如何处理数据流中的非负整数,将其总结为不相交的区间列表。通过两种算法实现:一是遍历法,二是结合二叉搜索树的高效算法,后者尤其适用于大量合并操作的场景。

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

原题地址:https://leetcode-cn.com/problems/data-stream-as-disjoint-intervals/submissions/

题目描述:

给定一个非负整数的数据流输入 a1,a2,…,an,…,将到目前为止看到的数字总结为不相交的间隔列表。

例如,假设数据流中的整数为 1,3,7,2,6,…,每次的总结为:

[1, 1]
[1, 1], [3, 3]
[1, 1], [3, 3], [7, 7]
[1, 3], [7, 7]
[1, 3], [6, 7]
 

进阶:
如果有很多合并,并且与数据流的大小相比,不相交间隔的数量很小,该怎么办?

提示:
特别感谢 @yunhong 提供了本问题和其测试用例。

 

解题方案:

首先使用的是最简单的办法,直接遍历一遍,没有用到二叉搜索树:

/**
 * 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 SummaryRanges {
public:
    /** Initialize your data structure here. */
    vector<Interval> ans;
    SummaryRanges() {
        
    }
    
    void addNum(int val) {
        Interval v(val, val);
        vector<Interval> tmp;
        if(!ans.size()){
            tmp.push_back(v);
        }
        else{
            int flag = 0;
            for(auto a : ans){
                if(a.end == v.start - 1){
                    v.start = a.start;
                }
                else if(a.start == v.end + 1){
                    v.end = a.end;
                }
                else if(a.end < v.start - 1){
                    tmp.push_back(a);
                }
                else if(a.start > v.end + 1){
                    if(!flag){
                        tmp.push_back(v);
                        flag = 1;
                    }
                    tmp.push_back(a);
                }
                else{
                    flag = 1;
                    tmp.push_back(a);
                }
            }
            if(!flag)
                tmp.push_back(v);
            
        }
        ans = tmp;
    }
    
    vector<Interval> getIntervals() {
        return ans;
    }
};

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges* obj = new SummaryRanges();
 * obj->addNum(val);
 * vector<Interval> param_2 = obj->getIntervals();
 */

学习时间最短的算法:

/**
 * 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 SummaryRanges {
public:
    /** Initialize your data structure here. */
    int n=0;
    vector<Interval> A;
    SummaryRanges() {
        
    }
    
    void addNum(int val) {
        int l=0,r=n-1,mid;
        Interval B;
        while(l<=r){
            mid=(l+r)>>1;
            if(A[mid].start>val) r=mid-1;
            else if(A[mid].end<val) l=mid+1;
            else break;
        }
        if(l<=r) return;
        if(r==-1){
            if(!n||A[l].start-1>val){
                B.start=B.end=val;
                A.insert(A.begin(),B);
                n++;
                return;
            }
            else 
                A[l].start=val;
                
            
        }
        if(A[r].end+1<val){
            if(l==n||A[l].start-1>val){
                B.start=B.end=val;
                A.insert(A.begin()+r+1,B);
                n++;
                return;
            }
            else {
                if(A[l].start-1==val) 
                    A[l].start=val;
            }
        }
        else{
            A[r].end=val;
            if(l<n&&A[r].end+1==A[l].start){
                A[r].end=A[l].end;
                A.erase(A.begin()+l);
                n--;
            }
        }
    }
    
    vector<Interval> getIntervals() {
        return A;
    }
};

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges* obj = new SummaryRanges();
 * obj->addNum(val);
 * vector<Interval> param_2 = obj->getIntervals();
 */

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值