Skip to content
advancedPhase 7 · Advanced Topics

Prefix Sum

Master prefix sums for range queries and subarray problems.

1h
5 problems
Topic Progress0%

Prefix Sum Fundamentals

What is Prefix Sum?

A Prefix Sum array precomputes cumulative sums, allowing O(1) range sum queries after O(n) preprocessing.

Key Formula

For array arr[0..n-1], prefix sum prefix[i] = sum of elements from 0 to i:

prefix[0] = arr[0]
prefix[i] = prefix[i-1] + arr[i] for i > 0

Range sum [l, r] = prefix[r] - (l > 0 ? prefix[l-1] : 0)

Example

arr = [3, 1, 4, 2, 5]
prefix = [3, 4, 8, 10, 15]

Sum [1,3] = prefix[3] - prefix[0] = 10 - 3 = 7 (1+4+2)
Sum [2,4] = prefix[4] - prefix[1] = 15 - 4 = 11 (4+2+5)

Implementation

public class PrefixSum {
    private int[] prefix;
    private int[] arr;
    
    public PrefixSum(int[] nums) {
        arr = nums;
        int n = nums.length;
        prefix = new int[n];
        prefix[0] = nums[0];
        for (int i = 1; i < n; i++) {
            prefix[i] = prefix[i - 1] + nums[i];
        }
    }
    
    // Range sum [l, r] inclusive (0-indexed)
    public int rangeSum(int l, int r) {
        if (l == 0) return prefix[r];
        return prefix[r] - prefix[l - 1];
    }
    
    // Get prefix sum at index i
    public int getPrefixSum(int i) {
        return prefix[i];
    }
}

2D Prefix Sum

For matrix range sum queries:

public class PrefixSum2D {
    private int[][] prefix;
    private int m, n;
    
    public PrefixSum2D(int[][] matrix) {
        m = matrix.length;
        n = matrix[0].length;
        prefix = new int[m + 1][n + 1];
        
        for (int i = 1; i <= m; i++) {
            for (int j = 1; j <= n; j++) {
                prefix[i][j] = matrix[i-1][j-1]
                    + prefix[i-1][j] + prefix[i][j-1]
                    - prefix[i-1][j-1];
            }
        }
    }
    
    // Sum of submatrix from (r1,c1) to (r2,c2) (0-indexed)
    public int rangeSum(int r1, int c1, int r2, int c2) {
        return prefix[r2+1][c2+1]
             - prefix[r1][c2+1]
             - prefix[r2+1][c1]
             + prefix[r1][c1];
    }
}

Time Complexity

  • Build: O(n) for 1D, O(mn) for 2D
  • Query: O(1)
  • Space: O(n) for 1D, O(mn) for 2D

Advanced Prefix Sum Applications

Prefix Sum + Hash Map

Combining prefix sums with hash maps enables efficient subarray problems.

Subarray Sum Equals K

public int subarraySum(int[] nums, int k) {
    Map<Integer, Integer> prefixCount = new HashMap<>();
    prefixCount.put(0, 1);
    
    int prefixSum = 0;
    int count = 0;
    
    for (int num : nums) {
        prefixSum += num;
        
        // If (prefixSum - k) exists, we found subarrays summing to k
        if (prefixCount.containsKey(prefixSum - k)) {
            count += prefixCount.get(prefixSum - k);
        }
        
        prefixCount.put(prefixSum, prefixCount.getOrDefault(prefixSum, 0) + 1);
    }
    
    return count;
}

Find Pivot Index

public int pivotIndex(int[] nums) {
    int totalSum = 0;
    for (int num : nums) totalSum += num;
    
    int leftSum = 0;
    for (int i = 0; i < nums.length; i++) {
        if (leftSum == totalSum - leftSum - nums[i]) {
            return i;
        }
        leftSum += nums[i];
    }
    
    return -1;
}

Contiguous Array (Equal 0s and 1s)

public int findMaxLength(int[] nums) {
    Map<Integer, Integer> prefixMap = new HashMap<>();
    prefixMap.put(0, -1);
    
    int prefixSum = 0;
    int maxLen = 0;
    
    for (int i = 0; i < nums.length; i++) {
        prefixSum += (nums[i] == 1) ? 1 : -1;
        
        if (prefixMap.containsKey(prefixSum)) {
            maxLen = Math.max(maxLen, i - prefixMap.get(prefixSum));
        } else {
            prefixMap.put(prefixSum, i);
        }
    }
    
    return maxLen;
}

Product of Array Except Self (Prefix Product)

public int[] productExceptSelf(int[] nums) {
    int n = nums.length;
    int[] result = new int[n];
    
    // Left products
    result[0] = 1;
    for (int i = 1; i < n; i++) {
        result[i] = result[i - 1] * nums[i - 1];
    }
    
    // Right products
    int rightProduct = 1;
    for (int i = n - 1; i >= 0; i--) {
        result[i] *= rightProduct;
        rightProduct *= nums[i];
    }
    
    return result;
}

Practice Problems

0/1solved
Subarray Sum Equals K
Prefix Sum + Hash Map

Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k.

Example:

Input: nums = [1,1,1], k = 2

Output: 2

[1,1] appears twice as a contiguous subarray.

Solution
```java
public int subarraySum(int[] nums, int k) {
    Map<Integer, Integer> prefixCount = new HashMap<>();
    prefixCount.put(0, 1);
    
    int prefixSum = 0;
    int count = 0;
    
    for (int num : nums) {
        prefixSum += num;
        
        if (prefixCount.containsKey(prefixSum - k)) {
            count += prefixCount.get(prefixSum - k);
        }
        
        prefixCount.put(prefixSum, prefixCount.getOrDefault(prefixSum, 0) + 1);
    }
    
    return count;
}
```

Edge Cases:

  • Array contains negative numbers
  • k = 0 (count subarrays with sum 0)
  • Single element array
  • All elements are the same

Quiz

1. What is the time complexity to answer a range sum query using a prefix sum array?

Question 1 options

2. Why do we initialize the hash map with {0: 1} in the subarray sum problem?

Question 2 options

3. What is the primary purpose of Prefix Sum?

Question 3 options

4. What is a common mistake when implementing Prefix Sum?

Question 4 options

Flashcards

Question

How do you compute range sum [l, r] using prefix sums?

Answer

rangeSum(l, r) = prefix[r] - (l > 0 ? prefix[l-1] : 0). This gives O(1) range sum queries after O(n) preprocessing.

Question

When should you combine prefix sums with hash maps?

Answer

Use prefix sum + hash map when you need to find subarrays with a specific sum, count subarrays with certain properties, or find subarrays with equal numbers of two types of elements.

Question

What is Prefix Sum?

Answer

Prefix Sum is a key concept in software engineering.

Question

When to use Prefix Sum?

Answer

Use Prefix Sum when building production systems that require reliability, scalability, and maintainability.

Question

Prefix Sum best practices

Answer

Follow SOLID principles, write clean code, test thoroughly, document decisions, and monitor in production.

Revision Notes

Key Takeaways

  • 1.Prefix sums enable O(1) range sum queries after O(n) preprocessing
  • 2.2D prefix sums work similarly for matrix range queries
  • 3.Combining prefix sums with hash maps solves many subarray problems
  • 4.Initialize hash map with {0: 1} to handle subarrays starting from index 0
  • 5.Prefix products work the same way for multiplicative problems

Interview Tips

  • For range sum queries, always consider prefix sums first
  • Hash map + prefix sum is powerful for finding subarrays with specific sums
  • Remember the formula: sum(l,r) = prefix[r] - prefix[l-1]
  • For 2D problems, use inclusion-exclusion principle with prefix sums
  • Practice: Subarray Sum Equals K, Range Sum Query, Contiguous Array

Cheat Sheet

Prefix Sum Cheat Sheet

1D Prefix Sum

int[] prefix = new int[n];
prefix[0] = arr[0];
for (int i = 1; i < n; i++)
    prefix[i] = prefix[i-1] + arr[i];

// Range sum [l, r]
int rangeSum(int l, int r) {
    return l == 0 ? prefix[r] : prefix[r] - prefix[l-1];
}

2D Prefix Sum

prefix[i][j] = matrix[i-1][j-1]
             + prefix[i-1][j] + prefix[i][j-1]
             - prefix[i-1][j-1];

// Range sum (r1,c1) to (r2,c2)
return prefix[r2+1][c2+1] - prefix[r1][c2+1]
     - prefix[r2+1][c1] + prefix[r1][c1];

Prefix Sum + Hash Map

Map<Integer, Integer> prefixCount = new HashMap<>();
prefixCount.put(0, 1);
int prefixSum = 0, count = 0;
for (int num : nums) {
    prefixSum += num;
    if (prefixCount.containsKey(prefixSum - k))
        count += prefixCount.get(prefixSum - k);
    prefixCount.merge(prefixSum, 1, Integer::sum);
}

Applications

  1. Range Sum Queries: O(1) after O(n) build
  2. Subarray Sum Equals K
  3. Contiguous Array (equal 0s and 1s)
  4. Pivot Index
  5. Product of Array Except Self