Range Sum Query - Immutable

EasyPrefix Sum · Design🧩 Prefix SumLeetCode #303 ↗Updated

Problem

Design a class NumArray that is built once from an integer array nums (which never changes afterwards) and then answers many queries sumRange(left, right): the sum of nums[left..right], both ends inclusive.
Input[-2,0,3,-5,2,-1], (0,2)Output1
Inputsame array, (2,5)Output-1
Inputsame array, (0,5)Output-3

1 ≤ n ≤ 104  ·  -105 ≤ nums[i] ≤ 105  ·  0 ≤ left ≤ right < n  ·  up to 104 queries

Try it yourself

Java
class NumArray {
    public NumArray(int[] nums) {
        
    }

    public int sumRange(int left, int right) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
The array is read-only, so pay once up front: with prefix[i] = sum of the first i elements, any range sum is just prefix[right+1] - prefix[left].
PatternPrefix Sum

Instinct Repeated range-sum queries, or "count subarrays whose sum equals / divides K" with negatives allowed? Store running totals and subtract two of them.

Memory hack Any range is two prefixes apart - sum(i..j) = P[j+1] - P[i], so remember every P you've passed.

Open the Prefix Sum guide →

Approaches

Brute ForceLoop Over the Range per Query

Time O(1) init · O(n)/querySpace O(1) extra

Keep a reference to nums and, on every query, add up nums[left] through nums[right]. Nothing is reused between queries.

Java
class NumArray {
    private int[] nums;
    public NumArray(int[] nums) {
        this.nums = nums;
    }
    public int sumRange(int left, int right) {
        int sum = 0;
        for (int k = left; k <= right; k++) sum += nums[k];
        return sum;
    }
}

Trivial, but q queries cost O(q · n) — up to 108 steps.

At a glance

LevelApproachTimeSpace
Brute ForceLoop Over the Range per QueryO(1) init · O(n)/queryO(1) extra
BetterPrecompute Every Range (2-D Cache)O(n2) init · O(1)/queryO(n2)
OptimalPrefix Sum ArrayO(n) init · O(1)/queryO(n)
Common pitfalls
  • Off-by-one: with a size-n+1 array use prefix[right+1] - prefix[left].
  • Size-n prefix without the leading 0 → needs a special case for left == 0.
  • Recomputing sums inside sumRange — defeats the purpose of the design.
Interview tips
  • Ask how many queries vs. updates: immutable data favours heavy preprocessing.
  • Explain the space/time trade-off between the 2-D cache and the prefix array.
  • Mention the mutable follow-up (LC 307) needs a Fenwick or segment tree.
Pattern
Prefix sums → many range-sum queries on a static array.
My notes saved in this browser