algorithms

Advanced Array Interview Patterns: Prefix Sum, Difference Array, and Kadane’s Algorithm (2025)

Advanced Array Interview Patterns

Mastering a handful of array techniques unlocks dozens of LeetCode problems. This guide covers the six most important patterns tested at top companies in 2025.

1. Prefix Sum

Precompute prefix[i] = sum of arr[0..i-1] (with prefix[0] = 0). A range sum query [l, r] then answers in O(1):

prefix[r+1] - prefix[l]

Build time: O(n). Query time: O(1). Space: O(n).

Python Implementation

def build_prefix(arr):
    prefix = [0] * (len(arr) + 1)
    for i, v in enumerate(arr):
        prefix[i + 1] = prefix[i] + v
    return prefix

def range_sum(prefix, l, r):
    return prefix[r + 1] - prefix[l]

2D Prefix Sum

For rectangle sum queries on a matrix, extend to two dimensions:

def build_2d_prefix(matrix):
    m, n = len(matrix), len(matrix[0])
    dp = [[0] * (n + 1) for _ in range(m + 1)]
    for i in range(1, m + 1):
        for j in range(1, n + 1):
            dp[i][j] = (matrix[i-1][j-1]
                        + dp[i-1][j]
                        + dp[i][j-1]
                        - dp[i-1][j-1])
    return dp

def rect_sum(dp, r1, c1, r2, c2):
    return (dp[r2+1][c2+1]
            - dp[r1][c2+1]
            - dp[r2+1][c1]
            + dp[r1][c1])

Key problems: LC 303 (Range Sum Query – Immutable), LC 304 (2D Range Sum Query).

2. Difference Array

When you need many range-update operations (add val to arr[l..r]) followed by a read pass, the difference array gives O(1) per update and O(n) reconstruction.

def apply_range_updates(n, updates):
    diff = [0] * (n + 1)
    for l, r, val in updates:
        diff[l] += val
        diff[r + 1] -= val
    # reconstruct
    result = []
    cur = 0
    for i in range(n):
        cur += diff[i]
        result.append(cur)
    return result

Key problem: LC 1109 (Corporate Flight Bookings).

3. Kadane’s Algorithm

Maximum subarray sum in O(n):

def max_subarray(nums):
    max_sum = cur = nums[0]
    for n in nums[1:]:
        cur = max(n, cur + n)
        max_sum = max(max_sum, cur)
    return max_sum

Key problem: LC 53 (Maximum Subarray).

Variant: Maximum Circular Subarray (LC 918)

The answer is either the maximum subarray in the linear array, or the total sum minus the minimum subarray (wrapping case):

def max_circular_subarray(nums):
    total = sum(nums)
    max_sum = max_cur = nums[0]
    min_sum = min_cur = nums[0]
    for n in nums[1:]:
        max_cur = max(n, max_cur + n)
        max_sum = max(max_sum, max_cur)
        min_cur = min(n, min_cur + n)
        min_sum = min(min_sum, min_cur)
    if max_sum < 0:
        return max_sum  # all negatives
    return max(max_sum, total - min_sum)

Variant: Maximum Subarray Product (LC 152)

Track both max and min at each position because a negative times a negative flips to a large positive:

def max_product(nums):
    res = max_p = min_p = nums[0]
    for n in nums[1:]:
        candidates = (n, max_p * n, min_p * n)
        max_p, min_p = max(candidates), min(candidates)
        res = max(res, max_p)
    return res

4. Two-Pointer Techniques on Sorted Arrays

Two pointers starting from opposite ends solve several classic problems in O(n):

Container With Most Water (LC 11)

def max_area(height):
    l, r = 0, len(height) - 1
    best = 0
    while l < r:
        best = max(best, (r - l) * min(height[l], height[r]))
        if height[l] < height[r]:
            l += 1
        else:
            r -= 1
    return best

Trapping Rain Water (LC 42)

def trap(height):
    l, r = 0, len(height) - 1
    left_max = right_max = water = 0
    while l < r:
        if height[l] <= height[r]:
            left_max = max(left_max, height[l])
            water += left_max - height[l]
            l += 1
        else:
            right_max = max(right_max, height[r])
            water += right_max - height[r]
            r -= 1
    return water

5. Dutch National Flag (3-Way Partition)

Sort an array of 0s, 1s, and 2s in one pass with O(1) space (LC 75 Sort Colors):

def sort_colors(nums):
    lo = mid = 0
    hi = len(nums) - 1
    while mid <= hi:
        if nums[mid] == 0:
            nums[lo], nums[mid] = nums[mid], nums[lo]
            lo += 1; mid += 1
        elif nums[mid] == 1:
            mid += 1
        else:
            nums[mid], nums[hi] = nums[hi], nums[mid]
            hi -= 1

Invariant: nums[0..lo-1] == 0, nums[lo..mid-1] == 1, nums[hi+1..n-1] == 2.

6. Jump Game Variants

LC 55 – Can Reach End?

Track the furthest reachable index greedily:

def can_jump(nums):
    reach = 0
    for i, v in enumerate(nums):
        if i > reach:
            return False
        reach = max(reach, i + v)
    return True

LC 45 – Minimum Jumps

def jump(nums):
    jumps = cur_end = cur_far = 0
    for i in range(len(nums) - 1):
        cur_far = max(cur_far, i + nums[i])
        if i == cur_end:
            jumps += 1
            cur_end = cur_far
    return jumps

Complexity Summary

Pattern Build Query/Update Space
Prefix Sum O(n) O(1) query O(n)
2D Prefix Sum O(mn) O(1) query O(mn)
Difference Array O(n) O(1) update, O(n) reconstruct O(n)
Kadane – O(n) O(1)
Two Pointer – O(n) O(1)
Dutch National Flag – O(n) O(1)
Jump Game Greedy – O(n) O(1)

Interview Tips

  • Prefix sum is the default tool any time you see repeated range sum queries – build it before the loop.
  • Difference array pairs with prefix sum: use it when updates are more frequent than reads.
  • For Kadane variants, draw out the recurrence explicitly before coding – interviewers want to see you derive it.
  • Dutch National Flag invariant is easy to mess up at boundaries; state the invariant out loud before coding.
  • Jump Game greedy: the key insight is that you only increment jumps when you exhaust the current jump range.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

newsletter

What's actually being asked right now

Interview patterns & comp trends, straight to your inbox.

No spam. Unsubscribe anytime.

1972 Soviet postage stamp commemorating the Mars 2 probe

worth a read

Mars For The Rest of Us — a weekly-or-more deep dive on the technical side of Mars exploration: rocket propulsion, microbiology, mission architecture, and everything in between. Written by Maciej Ceglowski.

Read it on Substack →
Scroll to Top