715.Range模块
链接:715.Range模块
难度:Hard
标签:设计、线段树、有序集合
简介:Range模块是跟踪数字范围的模块。设计一个数据结构来跟踪表示为 半开区间 的范围并查询它们。
题解 1 - cpp
- 编辑时间:2022-06-20
- 执行用时:200ms
- 内存消耗:66.95MB
- 编程语言:cpp
- 解法介绍:有序集合。
class RangeModule {
public:
RangeModule() {}
void addRange(int left, int right) {
auto it = intervals.upper_bound(left);
if (it != intervals.begin()) {
auto start = prev(it);
if (start->second >= right) {
return;
}
if (start->second >= left) {
left = start->first;
intervals.erase(start);
}
}
while (it != intervals.end() && it->first <= right) {
right = max(right, it->second);
it = intervals.erase(it);
}
intervals[left] = right;
}
bool queryRange(int left, int right) {
auto it = intervals.upper_bound(left);
if (it == intervals.begin()) {
return false;
}
it = prev(it);
return right <= it->second;
}
void removeRange(int left, int right) {
auto it = intervals.upper_bound(left);
if (it != intervals.begin()) {
auto start = prev(it);
if (start->second >= right) {
int ri = start->second;
if (start->first == left) {
intervals.erase(start);
}
else {
start->second = left;
}
if (right != ri) {
intervals[right] = ri;
}
return;
}
else if (start->second > left) {
start->second = left;
}
}
while (it != intervals.end() && it->first < right) {
if (it->second <= right) {
it = intervals.erase(it);
}
else {
intervals[right] = it->second;
intervals.erase(it);
break;
}
}
}
private:
map<int, int> intervals;
};
题解 2 - python
- 编辑时间:2023-11-12
- 执行用时:480ms
- 内存消耗:20.4MB
- 编程语言:python
- 解法介绍:有序数组,每次合并数组。
from sortedcontainers import SortedList
class RangeModule:
def __init__(self):
self.arr = SortedList([(-1, -1), (inf, inf)])
def addRange(self, left: int, right: int) -> None:
arr = self.arr
item = (left, right)
idx = arr.bisect_left(item)
if arr[idx - 1][1] >= left:
item = (arr[idx - 1][0], max(arr[idx - 1][1], item[1]))
arr.pop(idx - 1)
idx -= 1
while arr[idx][0] <= item[1]:
item = (item[0], max(arr[idx][1], item[1]))
arr.pop(idx)
arr.add(item)
def queryRange(self, left: int, right: int) -> bool:
arr = self.arr
idx = arr.bisect_right((left, inf))
return arr[idx - 1][0] <= left and arr[idx - 1][1] >= right
def removeRange(self, left: int, right: int) -> None:
arr = self.arr
idx = arr.bisect_left((left, right))
if arr[idx - 1][1] > left:
if arr[idx - 1][1] > right:
arr.add((right, arr[idx - 1][1]))
item = (arr[idx - 1][0], left)
arr.pop(idx - 1)
arr.add(item)
while arr[idx][1] <= right:
arr.pop(idx)
if arr[idx][0] <= right:
item = (right, arr[idx][1])
arr.pop(idx)
if item[0] != item[1]:
arr.add(item)