The simplest approach checks every possible subarray. For each starting index, we extend the subarray one element at a time, keeping a running sum. If the sum is divisible by k (i.e., sum % k == 0), we count it.
res = 0.i:curSum = 0.j from i to n - 1:nums[j] to curSum.curSum % k == 0, increment res.res.If two prefix sums have the same remainder when divided by k, their difference is divisible by k. So the subarray between those two positions has a sum divisible by k. We use a hash map to count how many times each remainder has appeared. For each new prefix sum, we check how many previous prefix sums share the same remainder.
prefixSum = 0, res = 0, and a hash map prefixCnt with {0: 1}.prefixSum.remain = prefixSum % k. Handle negative remainders by adding k if needed.prefixCnt[remain] to res.prefixCnt[remain] by 1.res.Since remainders when dividing by k are always in the range [0, k-1], we can use a fixed-size array instead of a hash map. This gives slightly better constant factors. We also handle negative numbers by adding k to the modulo result, ensuring all remainders are non-negative.
count of size k, initialized to zeros, with count[0] = 1.prefix = 0 and res = 0.prefix = (prefix + num % k + k) % k to handle negatives.count[prefix] to res.count[prefix].res.