跳到主要内容

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)