Skip to content

327. Count of Range Sum

Description

Given an integer array nums and two integers lower and upper, return the number of range sums that lie in [lower, upper] inclusive.

Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j inclusive, where i <= j.

 

Example 1:

Input: nums = [-2,5,-1], lower = -2, upper = 2
Output: 3
Explanation: The three ranges are: [0,0], [2,2], and [0,2] and their respective sums are: -2, -1, 2.

Example 2:

Input: nums = [0], lower = 0, upper = 0
Output: 1

 

Constraints:

  • 1 <= nums.length <= 105
  • -231 <= nums[i] <= 231 - 1
  • -105 <= lower <= upper <= 105
  • The answer is guaranteed to fit in a 32-bit integer.

 

Solutions

Solution: Binary Indexed Tree

  • Time complexity: O(nlogn)
  • Space complexity: O(n)

 

JavaScript

js
/**
 * @param {number[]} nums
 * @param {number} lower
 * @param {number} upper
 * @return {number}
 */
const countRangeSum = function (nums, lower, upper) {
  const n = nums.length;
  const prefixSum = new Array(n + 1).fill(0);

  for (let index = 0; index < n; index++) {
    prefixSum[index + 1] = prefixSum[index] + nums[index];
  }

  const sortedPrefixSum = Array.from(new Set(prefixSum)).sort((a, b) => a - b);
  const bit = Array.from({length: sortedPrefixSum.length + 2}).fill(0);

  const getIndex = value => {
    let left = 0;
    let right = sortedPrefixSum.length - 1;

    while (left <= right) {
      const mid = Math.floor((left + right) / 2);

      sortedPrefixSum[mid] >= value ? (right = mid - 1) : (left = mid + 1);
    }
    return left;
  };

  const updateBit = index => {
    while (index < bit.length) {
      bit[index] += 1;
      index += index & -index;
    }
  };

  const queryBit = index => {
    let count = 0;

    while (index > 0) {
      count += bit[index];
      index -= index & -index;
    }
    return count;
  };

  let result = 0;

  for (const sum of prefixSum) {
    const leftIndex = getIndex(sum - upper);
    const rightIndex = getIndex(sum - lower + 1);

    result += queryBit(rightIndex) - queryBit(leftIndex);
    updateBit(getIndex(sum) + 1);
  }
  return result;
};

Released under the MIT license