描述
实现一个数据结构, 支持对区间的动态tracking, 分别有以下三个操作:
addRange(int left, int right)
新增一个左闭右开的tracking区间[left, right)
.queryRange(int left, int right)
check区间[left, right)
是否正在被tracking, 返回布尔值.removeRange(int left, int right)
取消tracking这个区间.
思路
维护一个listindex
存当前有效的离散点. 这样这个list有以下特征:
index
必然是坐标left
和right
两两成组的interval list, 在加入和删除的过程中, 会自动merge.addRange()
:left
向左二分搜索插入点l
(下标),right
向右二分搜索插入点r
. 如果l
是偶数, 说明在它之前坐标们是两两成对的(可以在纸上画画), 当前点left
没有落入任何一个已有的区间内, 对于left
来说是一个独立点, 必然会存在与本轮更新后的index
中, 那么加入new_index
.right
同理. 最后更新index
的[l:r]
段为new_index
.queryRange()
和addRange()
稍有差别.left
向右二分搜索插入点l
(下标),right
向左二分搜索插入点r
. 如果l == r
, 说明这个被query的区间落在了index
的离散点们标示出的一个(而不是多个)区间内.同时l
和r
需要满足是奇数, 否则query区间实际落入的是gap,而不是index
标识的tracking区间.removeRange()
基本是addRange()
的逆操作. 当r
是奇数,说明在它之前坐标们没有两两成对, 这个点落入了已有区间中, 那么它在删除操作后会是一个新的区间边界点. 需要加入新的index
中.right
同理.
代码
1 | class RangeModule(object): |