Compile Ready
Module 3 · Prefix Sum Pattern

Range Sum Query - Immutable

EasyProblem 2 of 18 7 min read ~15 min to solve LeetCode
ArrayPrefix SumDesignRange Query
Asked atAmazonGoogleMicrosoftMetaBloomberg

Problem Statement

Design a class NumArray that is initialized with an integer array nums and supports sumRange(left, right), which returns the sum of elements from index left through index right inclusive.

Input

A constructor call NumArray(nums) followed by zero or more sumRange(left, right) queries.

Output

For each query, return the integer sum of nums[left] through nums[right].

Constraints

  • 1 <= nums.length <= 10^4
  • -10^5 <= nums[i] <= 10^5
  • 0 <= left <= right < nums.length
  • At most 10^4 calls will be made to sumRange

Examples

Example 1

Input:
nums = [-2,0,3,-5,2,-1], queries = sumRange(0,2), sumRange(2,5), sumRange(0,5)
Output: 1, -1, -3
Explanation: The queried sums are -2 + 0 + 3 = 1, then 3 - 5 + 2 - 1 = -1, then the whole array sum is -3.

Example 2

Input:
nums = [5], queries = sumRange(0,0)
Output: 5
Explanation: The only range contains the single value **5**.

Learning Objectives

  • Recognise many immutable range-sum queries as a prefix-sum preprocessing problem.
  • Use a leading zero in **prefix** to make inclusive ranges easy to subtract.
  • Separate constructor preprocessing cost from O(1) query cost.
  • Explain why immutability makes preprocessing especially powerful.

Intuition

Pattern Recognition

This is a prefix-sum design problem because the same array is queried many times and the array never changes. The tempting query implementation loops from left to right every time, which is acceptable for one query but wasteful for thousands.

Precompute a prefix array where prefix[i] stores the sum of the first i numbers. Then every inclusive range can be answered by subtracting the total before the range from the total through the range. The leading 0 at prefix[0] removes special cases for ranges that start at index 0.

Common mistakes

  • ×Building **prefix** with the same length as **nums** and then writing extra edge cases for **left = 0**.
  • ×Using **prefix[right] - prefix[left]** and accidentally excluding **nums[right]**.
  • ×Recomputing the range sum inside every query even though the array is immutable.
  • ×Forgetting that negative numbers are fine because subtraction of prefix totals still works.

Algorithm Explanation

Key idea

Build prefix with length n + 1, where prefix[0] = 0 and prefix[i + 1] = prefix[i] + nums[i]. The sum from left through right is the total through right minus the total before left, so sumRange(left, right) = prefix[right + 1] - prefix[left].

Walkthrough

For nums = [-2,0,3,-5,2,-1], the prefix array becomes [0,-2,-2,1,-4,-2,-3]. To answer sumRange(2,5), take prefix[6] - prefix[2] = -3 - -2 = -1. This subtracts away everything before index 2 and leaves exactly 3,-5,2,-1.

Algorithm

  1. In the constructor, allocate prefix with one extra slot.
  2. Set prefix[0] = 0 as the empty prefix before the array begins.
  3. For each index i, store prefix[i + 1] = prefix[i] + nums[i].
  4. For sumRange(left, right), return prefix[right + 1] - prefix[left].
  5. Do not modify prefix during queries because the original array is immutable.

Solutions

Solution: Precomputed prefix array

Pay O(n) once in the constructor to build a prefix array with a leading zero. Each range query then becomes one subtraction between two prefix totals.

Step-by-step

  1. Allocate prefix with nums.length + 1 entries.
  2. Fill prefix[index + 1] from left to right using the previous prefix total.
  3. For a query, read the prefix after right and subtract the prefix before left.
  4. Return the difference as the inclusive range sum.
Time

O(n) constructor, O(1) per query

Space

O(n)

The extra prefix array stores one running total for every boundary between elements.

Java implementation

Loading…

Dry Run

Sample input

nums = [-2,0,3,-5,2,-1]. Build prefix, then answer sumRange(2,5).

stepindex or queryprefix valueformula or rangeanswer
build0prefix[1] = -20 + -2not queried
build1prefix[2] = -2-2 + 0not queried
build2prefix[3] = 1-2 + 3not queried
build3prefix[4] = -41 + -5not queried
build4prefix[5] = -2-4 + 2not queried
build5prefix[6] = -3-2 + -1not queried
queryleft = 2, right = 5prefix[6] and prefix[2]-3 - -2-1

The prefix array stores sums at boundaries, so subtracting boundary 2 from boundary 6 isolates indices 2 through 5.

Interview Tips

Present this as a tradeoff: O(n) preprocessing buys O(1) queries because the array is immutable. Emphasize the extra leading zero because it is the detail that removes off-by-one edge cases. If the interviewer asks about updates, this exact structure no longer works efficiently and you can discuss Binary Indexed Trees or Segment Trees.

Likely follow-ups

  • How would the design change if **nums[index]** could be updated after construction?
  • How would you support range-sum queries on a 2D matrix?
  • What if the query asked for the average instead of the sum?
  • When would you choose a Segment Tree over a prefix array?

Similar Problems

Key Takeaways

  • A leading zero makes **prefix[right + 1] - prefix[left]** work for every inclusive range.
  • Immutable arrays are ideal for preprocessing because query work can be moved to construction.
  • Prefix sums answer range sums by subtracting away everything before the range.
  • Updates break the static-prefix assumption and call for different data structures.
Reusable template: For many immutable range queries, precompute boundary prefix totals once and answer each query by subtracting two boundaries.