力扣(LeetCode)- 327. 区间和的个数(JavaScript)
这题用到了有序集合,但是js没有这种集合总是超时。手动实现如下。
// 默认比较器,处理NaN,规则和Python保持一致:NaN比任何数大,两个NaN相等
function defaultCompare(a, b) {
if (Number.isNaN(a) && Number.isNaN(b)) return 0;
if (Number.isNaN(a)) return 1;
if (Number.isNaN(b)) return -1;
if (a < b) return -1;
if (a > b) return 1;
return 0;
}
class SortedList {
constructor(items = [], options = []) {
if (options.compare) {
this.compare = options.compare
} else {
this.compare = defaultCompare
}
// 内部存储数组,初始就排序
this._arr = [...items].sort(this.compare);
}
bisectLeft(target) {
let low = 0
let high = this._arr.length
while (low < high) {
const mid = Math.trunc((low + high) / 2)
if (this.compare(this._arr[mid], target) < 0) {
low = mid + 1
} else {
high = mid
}
}
return low
}
bisectRight(target) {
let low = 0
let high = this._arr.length
while (low < high) {
const mid = Math.trunc((low + high) / 2)
if (this.compare(this._arr[mid], target) <= 0) {
low = mid + 1
} else {
high = mid
}
}
return low
}
add(item) {
const pos = this.bisectLeft(item);
this._arr.splice(pos, 0, item);
}
}
这题解答方法
var countRangeSum = function(nums, lower, upper) {
const len = nums.length;
let count = 0
let sum = 0
const list = new SortedList([0])
for (let i = 0;i < len;i++) {
sum += nums[i]
const left = list.bisectLeft(sum - upper)
const right = list.bisectRight(sum - lower)
count += right - left
list.add(sum)
}
return count
};