【352困难】将数据流变为多个不相交区间

【352困难】将数据流变为多个不相交区间(2021.10.9)

1. 问题描述

给你一个由非负整数 a1, a2, ..., an 组成的数据流输入,请你将到目前为止看到的数字总结为不相交的区间列表。

实现 SummaryRanges 类:

  • SummaryRanges() 使用一个空数据流初始化对象。
  • void addNum(int val) 向数据流中加入整数 val
  • int[][] getIntervals() 以不相交区间 [starti, endi] 的列表形式返回对数据流中整数的总结。

示例:

输入:
["SummaryRanges", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals", "addNum", "getIntervals"]
[[], [1], [], [3], [], [7], [], [2], [], [6], []]
输出:
[null, null, [[1, 1]], null, [[1, 1], [3, 3]], null, [[1, 1], [3, 3], [7, 7]], null, [[1, 3], [7, 7]], null, [[1, 3], [6, 7]]]

解释:
SummaryRanges summaryRanges = new SummaryRanges();
summaryRanges.addNum(1);      // arr = [1]
summaryRanges.getIntervals(); // 返回 [[1, 1]]
summaryRanges.addNum(3);      // arr = [1, 3]
summaryRanges.getIntervals(); // 返回 [[1, 1], [3, 3]]
summaryRanges.addNum(7);      // arr = [1, 3, 7]
summaryRanges.getIntervals(); // 返回 [[1, 1], [3, 3], [7, 7]]
summaryRanges.addNum(2);      // arr = [1, 2, 3, 7]
summaryRanges.getIntervals(); // 返回 [[1, 3], [7, 7]]
summaryRanges.addNum(6);      // arr = [1, 2, 3, 6, 7]
summaryRanges.getIntervals(); // 返回 [[1, 3], [6, 7]]

提示:

  • 0 <= val <= 104
  • 最多调用 addNumgetIntervals 方法 3 * 104
2. 解题思路(并查集

x表示区间的低位,find(x)表示区间的高位

  1. 提前将未被访问的x初始化为-1
  2. 当插入val时,先判断val的高位是什么,如果为-1表示原来没有添加过-1,将其高位置为val
  3. 判断val-1是否被添加过,如果存在,将val-1的高位连接到val
  4. 然后,判断val+1是否存在,如果存在,将val的高位连接到val+1的高位
  5. 同时使用了路径压缩的优化方法

并查集教程

3. 代码
class SummaryRanges {
public:
    array<int, 10002> buff{0};
    int max = -1;

    // 注意遍历方式
    void init(){
        for(auto &i: buff) {
            i = -1;
        }
    }

    // 并查集中的查询函数
    int find(int x) {
        if(x < 0 || buff[x] == -1) {
            return -1;
        }
        return buff[x] == x ? x : (buff[x] = find(buff[x]));
    }

    // 并查集中的合并函数
    void quickLink(int x) {
        if(find(x) == -1) {
            buff[x] = x;
        }
        if(find(x-1) != -1) {
            buff[x-1] = x;
        }
        if(find(x+1) != -1) {
            buff[x] = buff[x+1];
        }
    }

    SummaryRanges() {
        init();
    }
    
    void addNum(int val) {
        quickLink(val);
        if(val > max) {
            max = val;
        }
    }
    
    vector<vector<int>> getIntervals() {
        int x = 0, fx = 0;
        vector<vector<int>> result;
        while(x <= max) {
            fx = find(x);
            if(fx == -1) {
                x++;
            } else {
                result.push_back( vector<int>{x,fx} );
                x = fx + 1;
            }
        }
        return result;
    }
};

/**
 * Your SummaryRanges object will be instantiated and called as such:
 * SummaryRanges* obj = new SummaryRanges();
 * obj->addNum(val);
 * vector<vector<int>> param_2 = obj->getIntervals();
 */
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值