Logo

Kode$word

Range Sum Query - Immutable

Range Sum Query - Immutable

LeetCode Question 303

8 views
0
0

LeetCode Problem 303

Link of the Problem to try -: Link


Given an integer array nums, handle multiple queries of the following type:

  1. Calculate the sum of the elements of nums between indices left and right inclusive where left <= right.

Implement the NumArray class:

  1. NumArray(int[] nums) Initializes the object with the integer array nums.
  2. int sumRange(int left, int right) Returns the sum of the elements of nums between indices left and right inclusive (i.e. nums[left] + nums[left + 1] + ... + nums[right]).


Example 1:

Input
["NumArray", "sumRange", "sumRange", "sumRange"]
[[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
Output
[null, 1, -1, -3]

Explanation
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return (-2) + 0 + 3 = 1
numArray.sumRange(2, 5); // return 3 + (-5) + 2 + (-1) = -1
numArray.sumRange(0, 5); // return (-2) + 0 + 3 + (-5) + 2 + (-1) = -3


Constraints:

  1. 1 <= nums.length <= 104
  2. -105 <= nums[i] <= 105
  3. 0 <= left <= right < nums.length
  4. At most 104 calls will be made to sumRange.


Solution:

Efficient Range Sum Queries using Prefix Sums

While this problem may initially seem challenging, the solution is remarkably elegant. The key is to shift the heavy lifting from the query phase to the initialization phase using a Prefix Sum array.


The Strategy

Instead of calculating the sum from scratch every time a range is requested, we use two steps:

  1. The Constructor: During initialization, we create a Prefix Sum array. Each index i in this new array stores the cumulative sum of all elements from the beginning of the original array up to i.
  2. The sumRange Method: To find the sum between a left and right pointer, we simply use the precalculated values. The sum of the range is calculated as:
  3. Sum(left, right) = PrefixSum[right] - PrefixSum[left - 1]


Why This is Better

By pre-calculating the sums in the constructor, we transform the sumRange operation from a slow O(n) search into a lightning-fast O(1) constant-time lookup. This approach is highly efficient for applications where the data remains the same but the number of queries is high.


Code:

class NumArray {
int[] ans ;
public NumArray(int[] nums) {
ans = new int[nums.length];
int pre =0;
for(int i=0;i<nums.length;i++){
pre += nums[i];
ans[i] = pre;

}
}

public int sumRange(int left, int right) {
if(left == 0) return ans[right];
return ans[right]-ans[left-1];
}
}

/**
* Your NumArray object will be instantiated and called as such:
* NumArray obj = new NumArray(nums);
* int param_1 = obj.sumRange(left,right);
*/