LeetCode每日一题之LeetCode352

352. 将数据流变为多个不相交区间

LeetCode352

给你一个由非负整数 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

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

题解:

我这里借鉴的是LeetCode的第56题合并区间问题的思想,题设要求我们将数字分为不想交的区间,则我们定义一个内部元素为长度为2的一维数组的List集合,取名为list,用它来保存每一个新增的区间,同时在getIntervals方法结束以后,更新其内容。

在**addNum(int val)**方法中:

我们选择的直接将**[val,val]**这样的区间添加到list集合中去

在**getIntervals()**方法中:

我们首先判断此时list集合是否为空:

  • 如果为空,则表示此时list集合一个区间都没有添加,则直接返回空集即可
  • 如果不为空,则我们定义一个新的结果集res,和list相同,同样为内部元素为长度为2的List集合,用其来存储不相交的结果集
    • 首先我们需要对list集合进行排序,按照区间的start值进行从小到大的排序
    • 然后我们依次取出list集合中的start和end的值,和前一个区间进行比较,如果满足能够合并的条件,则进行合并,然后将新的合并后的区间添加到res结果集中
    • 最后将list指向此时的res集合,并且将res以二维数组的形式进行返回

示例的执行流程图如下所示:

在这里插入图片描述

代码实现:

class SummaryRanges {

    List<int[]> list;
    public SummaryRanges() {
        list = new ArrayList<>();
    }

    public void addNum(int val) {
        list.add(new int[]{val,val});
    }

    public int[][] getIntervals() {
        if (!list.isEmpty()) {
            List<int[]> res = new ArrayList<>();
            Collections.sort(list,(o1,o2) -> o1[0] - o2[0]);
            for (int i = 0; i < list.size(); i++) {
                //获取当前排序后第i个区间的开始和结束值
                int start = list.get(i)[0],end = list.get(i)[1];
                if (res.size() == 0 || res.get(res.size() - 1)[1] < start - 1) {
                    res.add(new int[]{start,end});
                }else {
                    res.get(res.size() - 1)[1] = Math.max(res.get(res.size() - 1)[1],end);
                }
            }
            list = res;
            return list.toArray(new int[list.size()][]);
        }
        return new int[0][2];
    }
}

n list.toArray(new int[list.size()][]);
}
return new int[0][2];
}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值