Range Sum Query - Immutable
Prefix-sum precomputation — O(1) range sum after O(n) build.
2 min read
design prefix-sum
Problem#
Given a fixed integer array, answer many sumRange(i, j) queries returning the sum of nums[i..j] inclusive.
Examples#
nums=[-2,0,3,-5,2,-1]; sumRange(0,2)→1.sumRange(2,5)→-1;sumRange(0,5)→-3.
Constraints#
1 <= n <= 10^4, up to10^4queries.
Approach#
Build pre[i+1] = pre[i] + nums[i]. Then sumRange(i,j) = pre[j+1] - pre[i].
Solution#
class NumArray { vector<long long> pre;public: NumArray(vector<int>& nums) { pre.assign(nums.size() + 1, 0); for (int i = 0; i < (int)nums.size(); ++i) pre[i + 1] = pre[i] + nums[i]; } int sumRange(int left, int right) { return (int)(pre[right + 1] - pre[left]); }};type NumArray struct { pre []int}
func Constructor(nums []int) NumArray { pre := make([]int, len(nums)+1) for i, v := range nums { pre[i+1] = pre[i] + v } return NumArray{pre: pre}}
func (a *NumArray) SumRange(left int, right int) int { return a.pre[right+1] - a.pre[left]}from typing import List
class NumArray: def __init__(self, nums: List[int]) -> None: self.pre = [0] * (len(nums) + 1) for i, v in enumerate(nums): self.pre[i + 1] = self.pre[i] + v
def sumRange(self, left: int, right: int) -> int: return self.pre[right + 1] - self.pre[left]class NumArray { constructor(nums) { this.pre = new Array(nums.length + 1).fill(0); for (let i = 0; i < nums.length; i++) { this.pre[i + 1] = this.pre[i] + nums[i]; } }
sumRange(left, right) { return this.pre[right + 1] - this.pre[left]; }}class NumArray { private long[] pre;
public NumArray(int[] nums) { pre = new long[nums.length + 1]; for (int i = 0; i < nums.length; i++) { pre[i + 1] = pre[i] + nums[i]; } }
public int sumRange(int left, int right) { return (int) (pre[right + 1] - pre[left]); }}class NumArray { private pre: number[];
constructor(nums: number[]) { this.pre = new Array<number>(nums.length + 1).fill(0); for (let i = 0; i < nums.length; i++) { this.pre[i + 1] = this.pre[i] + nums[i]; } }
sumRange(left: number, right: number): number { return this.pre[right + 1] - this.pre[left]; }}Editorial#
Shifting the prefix array by one slot eliminates the i == 0 special case — pre[0] = 0 cleanly represents “sum of empty prefix”. A long long guards against accidental overflow when the input has many large negatives or positives.
Complexity#
- Time:
O(n)init,O(1)per query. - Space:
O(n).
Concept revision#
Related#