Range Sum Query - Immutable
Given an integer array numsnums[left..right]NumArraysumRange(left, right)
Example 1
sumRange(0, 2) → 1 (-2 + 0 + 3)
sumRange(2, 5) → -1 (3 - 5 + 2 - 1)
sumRange(0, 5) → -3
How to Think About It
Step 1: Adding up each range is wasteful
Summing nums[left..right]
Step 2: Store running totals once
In the constructor, build prefixprefix[i]iprefix[0] = 0
Step 3: A range is a difference of two totals
The sum up to rightleft
sumRange(left, right) = prefix[right + 1] - prefix[left]
The extra slot at the front means left = 0
Walkthrough
nums = [-2, 0, 3, -5, 2, -1]prefix = [0, -2, -2, 1, -4, -2, -3]
| Query | prefix[right + 1] | prefix[left] | Answer |
|---|---|---|---|
| (0, 2) | 1 | 0 | 1 |
| (2, 5) | -3 | -2 | -1 |
| (0, 5) | -3 | 0 | -3 |
Java Solution
All the work happens once in the constructor; each query is a single subtraction.
public class RangeSumQueryImmutable {
private final int[] prefix; // prefix[i] = nums[0] + ... + nums[i-1]
public RangeSumQueryImmutable(int[] nums) {
prefix = new int[nums.length + 1];
for (int i = 0; i < nums.length; i++) {
prefix[i + 1] = prefix[i] + nums[i];
}
}
public int sumRange(int left, int right) {
return prefix[right + 1] - prefix[left]; // everything up to right, minus before left
}
public static void main(String[] args) {
RangeSumQueryImmutable q = new RangeSumQueryImmutable(new int[] {-2, 0, 3, -5, 2, -1});
System.out.println(q.sumRange(0, 2)); // 1
System.out.println(q.sumRange(2, 5)); // -1
System.out.println(q.sumRange(0, 5)); // -3
}
}
The original implementation,
Complexity
- Constructor: O(n) time, O(n) space.
- sumRange: O(1).
For a 2D grid, see