描述
实现一个数据结构, 支持对区间的动态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): |