Subarray Sums Divisible by K

MediumPrefix Sum · Remainder Counting🧩 Prefix SumLeetCode #974 ↗Updated

Problem

Given an integer array nums (values may be negative) and an integer k, count how many non-empty contiguous subarrays have a sum that is divisible by k.
Inputnums = [4,5,0,-2,-3,1], k = 5Output7
Inputnums = [5], k = 9Output0

1 ≤ n ≤ 3·104  ·  -104 ≤ nums[i] ≤ 104  ·  2 ≤ k ≤ 104

Try it yourself

Java
class Solution {
    public int subarraysDivByK(int[] nums, int k) {
        
    }
}
Your code is saved in this browser.Submit on LeetCode ↗
Key insight
Two prefix sums with the same remainder mod k bound a subarray divisible by k. So for each prefix, the number of good subarrays ending here equals how many earlier prefixes share its remainder.
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 ForceAll Subarrays with Running Sum

Time O(n2)Space O(1)

For every start index, extend the end while maintaining the running sum and count each time sum % k == 0. In Java, % of a negative number is negative or zero, but zero still means divisible, so the test is safe.

Java
public int subarraysDivByK(int[] nums, int k) {
    int count = 0;
    for (int start = 0; start < nums.length; start++) {
        int sum = 0;
        for (int end = start; end < nums.length; end++) {
            sum += nums[end];
            if (sum % k == 0) count++;
        }
    }
    return count;
}

About 4.5·108 steps at the limit — too slow.

At a glance

LevelApproachTimeSpace
Brute ForceAll Subarrays with Running SumO(n2)O(1)
OptimalRemainder Frequency ArrayO(n + k)O(k)
Common pitfalls
  • Indexing freq[sum % k] with a negative sum — ArrayIndexOutOfBoundsException.
  • Forgetting freq[0] = 1 — misses subarrays starting at index 0.
  • Incrementing freq[rem] before adding it — counts the empty subarray.
Interview tips
  • Say the identity first: equal prefix remainders ⇔ divisible subarray sum.
  • Call out Java's negative modulo explicitly; interviewers look for it.
  • Contrast with LC 523: counting needs frequencies, existence-with-length needs indices.
Pattern
Prefix sum + remainder frequency → count subarrays whose sum satisfies a modular condition.
My notes saved in this browser