352. Data Stream as Disjoint Intervals

本文介绍了一种使用链表数据结构处理大量合并操作的算法,针对数据流中非连续区间较少的情况,实现对输入数据流的有效总结。通过实例演示了如何在接收到一系列非负整数时,将出现过的数字概括为不相交的区间列表。

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

题目

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?

思路

题目要求是合并多,而且不连续的interval相比输入的数据量比较少,所以这边选择用链表来作为存储的数据结构。插入时基本就是按要求来,该合并合并该插入新的就插入新的,输出时遍历一遍就可以。

代码

/**
 * 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:
    struct Node{
        Interval intv;
        Node *next;
        Node() : intv(-2, -2), next(NULL) {}
        Node(int s, int e) : intv(s, e), next(NULL) {}
    };
    Node *pBegin;
    /** Initialize your data structure here. */
    SummaryRanges() {
        pBegin = new Node();
    }
    
    void addNum(int val) {
        Node *pCur = pBegin, *pNext, *pTemp;
        while((pCur->intv).end - val < -1){
            if(pCur->next == NULL){
                pCur->next = new Node(val, val);
                return;
            }
            pNext = pCur->next;
            if((pNext->intv).start >= val){
                if((pNext->intv).start <= val+1){
                    (pNext->intv).start = val;
                    return;
                }
                else{
                    pTemp = pCur->next;
                    pCur->next = new Node(val, val);
                    pCur->next->next = pTemp;
                    return;
                }
            }
            else if((pNext->intv).end >= val)
                return;
            pCur = pCur->next;
        }
        (pCur->intv).end = val;
        if(pCur->next == NULL)
            return;
        pNext = pCur->next;
        if((pNext->intv).start - val == 1){
            (pCur->intv).end = (pNext->intv).end;
            pCur->next = pNext->next;
            delete[] pNext;
        }        else
            (pCur->intv).end = val;
        return;
    }
    
    vector<Interval> getIntervals() {
        Node *pCur = pBegin->next;
        vector<Interval> vOut;
        while(pCur != NULL){
            vOut.push_back(pCur->intv);
            pCur = pCur->next;
        }
        return vOut;
    }
};

感想

写代码的时候感觉思路比较乱,想不大清楚判断的顺序应该怎么写比较好,最后莫名其妙就通过了,但代码看着就很丑。。。等啥时候有时间再看看怎么调整吧。另外,如果题目的要求反过来,合并比较少分开的interval很多的话思路应该要改变,主要的时间消耗应该会在搜索上,那可能一些近似平衡的二叉树结构会更快一下吧。

<think>好的,我现在需要帮助用户理解Java中的Collections.disjoint方法。首先,我得回忆一下这个方法的具体作用。根据用户提供的引用内容,特别是引用[2]中提到,disjoint方法返回true表示两个集合没有相同元素。这说明它的主要用途是判断两个集合是否互不相交,也就是没有共同的元素。 接下来,我需要确认方法的语法。根据引用[2]中的代码示例,方法签名是Boolean boolean = Collections.disjoint(Collection<?> c1, Collection<?> c2)。这里要注意参数是两个集合,返回值是布尔类型。当两个集合没有公共元素时返回true,否则返回false。 然后,我应该考虑用户可能的疑问点,比如方法的实际应用场景。例如,在处理多个集合时,需要检查它们是否完全没有交集,这时候disjoint方法就很有用。比如用户权限验证,检查用户是否有重复权限等场景。 另外,用户可能想知道这个方法的使用注意事项。比如,如果其中一个集合是null,会不会抛出异常?根据Java文档,如果传入的任一集合为null,disjoint方法会抛出NullPointerException,所以在使用时需要确保两个集合都不为null。 还需要考虑性能问题。这个方法的时间复杂度如何?一般来说,disjoint方法会遍历其中一个集合,检查每个元素是否存在于另一个集合中。如果其中一个集合是Set类型,contains方法的时间复杂度是O(1),所以整体复杂度接近O(n),其中n是较小集合的大小。但如果两个都是List类型,contains方法的时间复杂度是O(m),这样总的时间复杂度会是O(n*m),可能影响性能。因此,在处理大数据量时,可能需要优化,比如将其中一个集合转换为Set。 用户可能还想看具体的代码示例,比如如何正确使用这个方法。例如,创建两个List或Set,然后调用Collections.disjoint,并输出结果。这可以帮助用户更直观地理解方法的行为。 此外,应该提到方法的返回值含义,以及如何处理结果。比如,如果返回true,说明两个集合没有交集,可以执行某些操作;如果返回false,说明存在交集,需要处理重复元素的情况。 最后,需要总结一下disjoint方法的关键点,包括作用、参数、返回值、注意事项和性能考虑,帮助用户全面理解该方法的使用场景和限制。</think>### Java Collections.disjoint 方法详解 #### 1. 方法作用 `Collections.disjoint` 用于判断两个集合是否**没有公共元素**。若两个集合完全不相交(即无任何相同元素),则返回 `true`;反之返回 `false`[^2]。 #### 2. 方法语法 ```java boolean result = Collections.disjoint(Collection<?> c1, Collection<?> c2); ``` - **参数**:两个集合对象(支持 `List`、`Set` 等) - **返回值**:布尔值,表示两集合是否互斥 #### 3. 使用示例 ```java List<String> list1 = Arrays.asList("A", "B", "C"); Set<String> set1 = new HashSet<>(Arrays.asList("D", "E")); // 检查是否无交集 boolean noCommon = Collections.disjoint(list1, set1); System.out.println(noCommon); // 输出 true ``` #### 4. 注意事项 1. **空集合处理**:若任一集合为空,则直接返回 `true` 2. **null 校验**:传入 `null` 会抛出 `NullPointerException` 3. **性能优化**: - 当至少一个集合是 `Set` 时,时间复杂度为 $O(n)$(利用哈希查找) - 若均为 `List`,时间复杂度为 $O(n \times m)$(需要遍历检查) #### 5. 典型应用场景 - 权限系统:验证用户权限组是否冲突 - 数据清洗:检测两个数据集是否有重复记录 - 游戏开发:判断玩家道具包与商店物品是否重复
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值