GeeksforGeeks Medium

Longest Subarray with Sum K

Given an array (may contain negatives) and a target k, return the length of the longest subarray whose elements sum to exactly k.

arrayprefix-sumhash-table
Open on GeeksforGeeks ↗
02

Intuition

Every subarray sum is a difference of two prefix sums: sum(i..j) = pre[j] − pre[i−1]. So a subarray sums to k exactly when the current prefix minus some earlier prefix equals k. Store the first index where each prefix value occurred, and each new prefix asks: have I seen prefix − k before?

How to spot this pattern

Prefix sums plus a hash map of earliest index per prefix value. The identity is sum(i..j) = pre[j] - pre[i-1], so finding a subarray summing to k means finding an earlier prefix equal to pre - k. Storing only the first occurrence is what makes the found subarray as long as possible.

03

Approach

1

Why sliding window fails here

With negatives, growing the window can shrink the sum and shrinking can grow it — the window has no monotone signal to steer by. We need something that works for arbitrary signs: prefix sums.

2

Prefix sums turn subarrays into pairs

Walk once keeping the running sum pre. If some earlier prefix equaled pre − k, the elements after that point sum to exactly k. A hash map from prefix value → earliest index answers that in O(1).

3

Keep only the first occurrence

For the longest subarray we want the earliest index where each prefix value appeared, so never overwrite an existing entry. Seed the map with {0: -1} so subarrays starting at index 0 are counted.

04

Solution & live demo

1def longest_subarray_sum_k(nums, k):
2 first = {0: -1} # prefix value -> earliest index
3 pre = 0
4 best = 0
5 for i, n in enumerate(nums):
6 pre += n
7 if pre - k in first:
8 best = max(best, i - first[pre - k])
9 if pre not in first:
10 first[pre] = i
11 return best
05

Common pitfalls

Overwriting an existing prefix index

✗ Wrong
first[pre] = i
✓ Right
if pre not in first:
    first[pre] = i

For maximum length you want the earliest index that produced this prefix. Overwriting keeps the most recent one, which yields the shortest matching subarray instead of the longest.

Omitting the {0: -1} seed

✗ Wrong
first = {}
✓ Right
first = {0: -1}

A subarray starting at index 0 needs an empty prefix to subtract against, and its index must be -1 so the length computes as i - (-1) = i + 1. Without the seed, any answer beginning at the start is missed.

Assuming this works for all-positive arrays only

✗ Wrong
# sliding window with shrink-on-overshoot
✓ Right
if pre - k in first:
    best = max(best, i - first[pre - k])

A sliding window is valid only when every element is positive, since it relies on the sum growing monotonically. With negatives present the window may need to shrink and grow unpredictably — prefix sums handle both cases.

06

Edge cases

Subarray starts at index 0

The seed {0: -1} makes pre == k yield length i − (−1) = i + 1.

Prefix value repeats

Keep the first index only — a later duplicate would only shorten the candidate subarray.

07

Complexity

Time
O(n)
Space
O(n)
One pass; the map holds at most n+1 prefix values.