合并区间 LeetCode 56/57 BitSet 的妙用
合并区间问题
以数组 intervals
表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi]
。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
示例 1:
输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3] 和 [2,6] 重叠, 将它们合并为 [1,6].
示例 2:
输入:intervals = [[1,4],[4,5]]
输出:[[1,5]]
解释:区间 [1,4] 和 [4,5] 可被视为重叠区间。
提示:
1 <= intervals.length <= 10000
intervals[i].length == 2
0 <= starti <= endi <= 10000
思路
看到这道题的数据这么小, 我就直接想到用bit位
来记录每个位置是否被覆盖, 然后遍历导出, 我也确实这么做了, 但是我自己实现后实现相当复杂, 我就当时在想为什么这种需求按道理来说应该有现成的实现啊, 于是我找到了BitSet
, 不同于int
占用四个字节, boolean
占用一个字节, BitSet
粒度更细, 实现了在每个bit位
上来记录信息, 较为高效, 列举一些常用方法:
Modifier and Type | Method and Description |
---|---|
void |
and/or/xor(BitSet set) 与另一个BitSet 逻辑运算所有位 |
int |
cardinality() 返回值为true 的数量 |
void |
clear() 将所有位设置为 false |
void |
clear/flip/get(int bitIndex) 将指定位 false /补码/获取 |
void |
clear/flip/get(int fromIndex, int toIndex) 区间: [fromIndex,toIndex) |
boolean |
isEmpty() 是否包含 true |
int |
length() 最高位的索引 + 1 |
int |
nextClearBit(int fromIndex) 返回指定索引后第一个false 位的索引 |
int |
nextSetBit(int fromIndex) 返回指定索引后第一个true 位的索引 |
int |
previousClearBit(int fromIndex) /previousSetBit(int fromIndex) |
void |
set(int bitIndex) 将指定索引处的位设置为 true set(int bitIndex, boolean value) set(int fromIndex, int toIndex) 区间:[fromIndex,toIndex) set(int fromIndex, int toIndex, boolean value) |
int |
size() 返回实际使用的空间位数 |
那这样就相当简单了, 遍历加入所有情况, 然后遍历输出
但是注意! [0,1]
和[2,3]
这两个区间虽然紧挨着, 但是不可以合并, 我们需要× 2
来保证紧挨着的区间不会合并, 我这边直接使用了位移运算, 不过复杂度其实可达O(N^2)
|
|
同上, 57
题其实可以照抄过的, 但是多了个有序条件我们可以利用一下, 复杂度 O(N)
|
|
links: