题目
Version:0.9 StartHTML:0000000105 EndHTML:0000007516 StartFragment:0000000141 EndFragment:0000007476
class RangeList {
add(range) {}
remove(range) {}
print() {}
}
// Example run
const rl = new RangeList();
rl.add([1, 5]);
rl.print();// Should display: [1, 5)
rl.add([10, 20]);
rl.print();// Should display: [1, 5) [10, 20)
rl.add([20, 20]);
rl.print();// Should display: [1, 5) [10, 20)
rl.add([20, 21]);
rl.print();// Should display: [1, 5) [10, 21)
rl.add([2, 4]);
rl.print();// Should display: [1, 5) [10, 21)
rl.add([3, 8]);
rl.print();// Should display: [1, 8) [10, 21)
rl.remove([10, 10]);
rl.print();// Should display: [1, 8) [10, 21)
rl.remove([10, 11]);
rl.print();// Should display: [1, 8) [11, 21)
rl.remove([15, 17]);
rl.print();// Should display: [1, 8) [11, 15) [17, 21)
rl.remove([3, 19]);
rl.print(); // Should display: [1, 3) [19, 21)
答案:
class RangeList {
constructor() {
this.list = [];
}
reRank(list, i) {
const [min, max] = list[i];
let res = [...list];
// 记录需要更新的位置以及范围
let start = i;
let end = i;
let resMin = min;
let resMax = max;
// 判断是否与前一个范围重叠
if (i !== 0) {
const [preMin, preMax] = list[i - 1];
if (min <= preMax) {
// 与前一个范围重合,指针迁移
start = i - 1;
// 新的范围 min值调整为前一个范围
resMin = preMin;
}
}
let index = i + 1;
while(index < list.length) {
const [nextMin, nextMax] = list[index];
// 寻找右侧重复的范围
if (max >= nextMin && max <= nextMax) {
end = index;
resMax = nextMax;
break;
}
else if (max > nextMax){
end = index + 1;
}
index++;
}
res.splice(start, end - start + 1, [resMin, resMax]);
return res;
}
add(range) {
let list = [...this.list];
let [curMin, curMax] = range;
const len = list.length;
// 现有list长度为0时,直接push
if (len === 0) {
this.list.push(range);
return;
}
for(var i = 0; i < len; i++) {
const [min] = list[i];
if (curMin < min) {
// 先把范围插入到数组中
list.splice(i, 0, range);
// 重新排序
list = this.reRank(list, i);
break;
}
}
// 没有插入数组中
if (list.length === len && list[len - 1][1] < curMin) {
list.push(range);
}
else if (list.length === len && list[len - 1][1] >= curMin) {
list.splice(len - 1, 1, [list[len - 1][0], Math.max(list[len - 1][1], curMax)]);
}
this.list = list;
}
remove(range) {
// 当前需要移除的范围
let [curMin, curMax] = range;
let list = [...this.list];
for(let i = 0, l = list.length; i < l; i++) {
const [min, max] = this.list[i];
// 移除范围与当前范围有交集
if (!(curMin > max || curMax < min)) {
let arr = [];
// 左边需要移除
if (curMin <= min && curMax <= max) {
if (curMax + 1 !== max) {
arr.push([curMax + 1, max])
}
}
// 中间需要移除
else if (curMin > min && curMax < max){
arr.push([min, curMin], [curMax, max]);
}
// 右边需要移除
else {
if (min !== curMin) {
arr.push([min, curMin])
}
}
list.splice(i, 1, ...arr);
}
}
this.list = list;
}
print() {
const list = this.list;
let res = '';
for(let item in list) {
res += `[${list[item].toString()})`
}
return res;
}
}