Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

การนับ Range Sum ที่อยู่ในช่วง [lower, upper] ใน JavaScript

Range Sum

rangeSum(i, j) = ผลรวม elements ระหว่าง index i ถึง j (inclusive)

ปัญหา

นับจำนวน range sums ที่อยู่ใน [lower, upper]

ตัวอย่าง

arr = [1, 4, 3], lower = 2, upper = 5 -> output: 3

ตัวอย่างโค้ด

const arr = [1, 4, 3];
const upper = 5;
const lower = 2;

const countRangeSum = (arr = [], lower, upper) => {
  const sums = [0];
  let res = 0;
  let last = 0;
  let firstge = value => {
    let l = 0, r = sums.length, m;
    do {
      m = Math.floor((r + l) / 2);
      sums[m] < value ? l = m : r = m;
    } while (r >= l + 2);
    while (r > 0 && sums[r - 1] >= value) {
      r -= 1;
    }
    return r;
  };
  arr.forEach(num => {
    last += num;
    res += firstge(last - lower + 1) - firstge(last - upper);
    sums.splice(firstge(last), 0, last);
  });
  return res;
};

console.log(countRangeSum(arr, lower, upper));

ผลลัพธ์

3

คำอธิบาย

ใช้ prefix sums และ binary search (firstge = lower_bound)

สำหรับ prefix sum ปัจจุบัน S, ต้องการ prefix ก่อนหน้า P ที่ lower <= S - P <= upper

-> S - upper <= P <= S - lower

นับจำนวน P ใน sorted array sums ด้วย binary search

Time: O(n log n), Space: O(n)