Playbook / Staff+ coding / Prefix-sum subarray patterns (Staff+ follow-ups)

Prefix-sum subarray patterns (Staff+ follow-ups)

Expected question

"Given nums and k, return the number of contiguous subarrays whose sum equals k."

Variant forms

  • "Subarray sum equals K — prefix sum + hashmap."
  • "What if all nums are positive — can you use a sliding window?"
  • "Longest subarray with sum K."
  • "Subarray sum divisible by K."
  • "Count subarrays with product less than K."
  • "2D prefix sums for matrix region queries."
  • "How do negative numbers break the two-pointer approach?"
  • "State the invariant of the prefix-frequency map aloud."

The question, as it might actually be asked

Given nums and k, return the number of contiguous subarrays whose sum equals k.

How you'd talk while coding

I'd ask whether negatives are allowed — if yes, sliding window is wrong for exact-sum count. Brute is all i..j — O(n²). Correct is running prefix + map of how many times each prefix appeared: for each pref, add seen[pref - k], then increment seen[pref]. Seed seen[0] = 1. I'd say that invariant aloud. Tests: [1,1,1], k=2 → 2; [1,2,3], k=3 → 2. Staff+ stop line: "Name the sibling — positives may unlock a window for some variants; divisible-by-k uses prefix mod. I won't jump to segment trees for this medium."

Where this actually gets asked

Meta/Google-style medium family. Staff+ is graded on pattern recognition and saying which variant you're solving — not memorizing ten solutions.

Problem (primary)

Given nums and k, return the number of contiguous subarrays whose sum equals k.

Clarifying questions you should ask first

  1. Negatives allowed? (yes → can't use simple sliding window)
  2. Empty subarray count?
  3. Integer overflow concerns?
  4. Follow-up variants expected?

Approach ladder

StepIdea
BruteAll i..j sums — O(n²)
CorrectPrefix sums + hash map of counts — O(n)
Staff+Name sibling patterns and when window applies

Reference solution (Python)

from __future__ import annotations
from collections import defaultdict

def subarray_sum_equals_k(nums: list[int], k: int) -> int:
    pref = 0
    seen: dict[int, int] = defaultdict(int)
    seen[0] = 1
    ans = 0
    for x in nums:
        pref += x
        ans += seen[pref - k]
        seen[pref] += 1
    return ans

Complexity: O(n) time; O(n) space.

Verbal tests to narrate

  1. [1,1,1], k=2 → 2
  2. [1,2,3], k=3 → 2 ([1,2], [3])
  3. Zeros / negatives if in prompt

Pattern table (Staff+ talking track)

VariantTool
Sum equals k (with negatives)Prefix + hashmap
Binary array / at most K zerosSliding window
Shortest subarray sum ≥ K (positives)Window or deque on prefixes
Subarray sum divisible by kPrefix mod k map

What not to discuss

  • Jumping to segment trees for this medium
  • Using sliding window when negatives are allowed (wrong)

What's expected at each level

  • Mid-level: O(n²) works.
  • Senior: Prefix + map; explains why.
  • Staff+: Chooses correct pattern family; states when window fails.
  • Principal: Relates to real analytics / billing aggregation correctness.

Follow-up questions to expect

  • "What if all nums are positive?" — Window can apply for some variants (shortest sum ≥ k). For exact count equals k, the map still works and stays my default unless they want a window.