Subarray Sum Equals K
Problem Statement
Section titled “Problem Statement”Given an array of integers nums and an integer k, return the total number of subarrays whose sum equals to k. A subarray is a contiguous non-empty sequence of elements within an array.
Examples
Section titled “Examples”| Input | k | Output |
|---|---|---|
[1,1,1] | 2 | 2 |
[1,2,3] | 3 | 2 |
Constraints
Section titled “Constraints”1 <= nums.length <= 2×10^4-1000 <= nums[i] <= 1000-10^7 <= k <= 10^7
Real-World Applications
Section titled “Real-World Applications”Complexity Comparison
Section titled “Complexity Comparison”| Approach | Time | Space | Best When |
|---|---|---|---|
| Prefix Sum + Hash Map | O(n) | O(n) | Always — handles negatives too |
| Brute Force | O(n²) | O(1) | Understanding only |
Approach 1: Prefix Sum Hash Map (Recommended)
Section titled “Approach 1: Prefix Sum Hash Map (Recommended)”Keep a running prefix sum. Use a hash map count[prefix_sum] → occurrences. For each position, check if prefix_sum - k exists in the map — if it does, there are that many subarrays ending here that sum to k. Add the current prefix sum to the map after checking.
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [1,1,1], k = 2
| i | num | prefix | prefix−k | map (before check) | count added | map (after insert) |
|---|---|---|---|---|---|---|
| — | — | 0 | — | {} | — | {0:1} |
| 0 | 1 | 1 | -1 | {0:1} | 0 | {0:1, 1:1} |
| 1 | 1 | 2 | 0 | {0:1, 1:1} | 1 | {0:1, 1:1, 2:1} |
| 2 | 1 | 3 | 1 | {0:1, 1:1, 2:1} | 1 | {0:1, 1:1, 2:1, 3:1} |
Result: 2 (subarrays [1,1] at indices 0–1 and 1–2)
Input: nums = [1,2,3], k = 3
| i | num | prefix | prefix−k | map (before check) | count added |
|---|---|---|---|---|---|
| — | — | 0 | — | {} | — |
| 0 | 1 | 1 | -2 | {0:1} | 0 |
| 1 | 2 | 3 | 0 | {0:1, 1:1} | 1 |
| 2 | 3 | 6 | 3 | {0:1, 1:1, 3:1} | 1 |
Result: 2 (subarrays [1,2] and [3])
Animated walkthrough
Use Next or Autoplay to watch the running prefix sum, the map lookup, and the result accumulate for nums=[1,1,1], k=2.
Pseudocode
Section titled “Pseudocode”function subarraySum(nums, k): count = {0: 1} prefix = 0 result = 0 for num in nums: prefix += num result += count.get(prefix - k, 0) count[prefix] = count.get(prefix, 0) + 1 return resultSolution Code
Section titled “Solution Code”from typing import List
def subarray_sum_prefix_sum(nums: List[int], k: int) -> int: count = {0: 1} prefix = 0 result = 0 for num in nums: prefix += num result += count.get(prefix - k, 0) count[prefix] = count.get(prefix, 0) + 1 return result
print(subarray_sum_prefix_sum([1, 1, 1], k=2)) # 2print(subarray_sum_prefix_sum([1, 2, 3], k=3)) # 2#include <unordered_map>#include <vector>using namespace std;
class Solution {public: int subarraySum(vector<int>& nums, int k) { unordered_map<int, int> count; count[0] = 1; int prefix = 0, result = 0; for (int num : nums) { prefix += num; auto it = count.find(prefix - k); if (it != count.end()) { result += it->second; } count[prefix]++; } return result; }};import java.util.HashMap;import java.util.Map;
class Solution { public int subarraySum(int[] nums, int k) { Map<Integer, Integer> count = new HashMap<>(); count.put(0, 1); int prefix = 0, result = 0; for (int num : nums) { prefix += num; result += count.getOrDefault(prefix - k, 0); count.put(prefix, count.getOrDefault(prefix, 0) + 1); } return result; }}function subarraySum(nums, k) { const count = new Map([[0, 1]]); let prefix = 0, result = 0; for (const num of nums) { prefix += num; result += count.get(prefix - k) ?? 0; count.set(prefix, (count.get(prefix) ?? 0) + 1); } return result;}use std::collections::HashMap;
impl Solution { pub fn subarray_sum(nums: Vec<i32>, k: i32) -> i32 { let mut count: HashMap<i32, i32> = HashMap::new(); count.insert(0, 1); let mut prefix = 0; let mut result = 0; for num in nums { prefix += num; result += count.get(&(prefix - k)).copied().unwrap_or(0); *count.entry(prefix).or_insert(0) += 1; } result }}func subarraySum(nums []int, k int) int { count := map[int]int{0: 1} prefix, result := 0, 0 for _, num := range nums { prefix += num result += count[prefix-k] count[prefix]++ } return result}Approach 2: Brute Force
Section titled “Approach 2: Brute Force”Check every possible subarray using two nested loops. The outer loop picks the start index; the inner loop extends the window right, accumulating the sum. When the running sum equals k, increment the count.
Step-by-step Example
Section titled “Step-by-step Example”Input: nums = [1,2,3], k = 3
| i | j | running sum | == k? |
|---|---|---|---|
| 0 | 0 | 1 | no |
| 0 | 1 | 3 | yes → count=1 |
| 0 | 2 | 6 | no |
| 1 | 1 | 2 | no |
| 1 | 2 | 5 | no |
| 2 | 2 | 3 | yes → count=2 |
Result: 2
Pseudocode
Section titled “Pseudocode”function subarraySum(nums, k): result = 0 for i in range(len(nums)): total = 0 for j in range(i, len(nums)): total += nums[j] if total == k: result += 1 return resultSolution Code
Section titled “Solution Code”from typing import List
def subarray_sum_brute_force(nums: List[int], k: int) -> int: result = 0 for i in range(len(nums)): total = 0 for j in range(i, len(nums)): total += nums[j] if total == k: result += 1 return result
print(subarray_sum_brute_force([1, 1, 1], k=2)) # 2print(subarray_sum_brute_force([1, 2, 3], k=3)) # 2#include <vector>using namespace std;
class Solution {public: int subarraySum(vector<int>& nums, int k) { int result = 0; for (int i = 0; i < (int)nums.size(); i++) { int total = 0; for (int j = i; j < (int)nums.size(); j++) { total += nums[j]; if (total == k) result++; } } return result; }};class Solution { public int subarraySum(int[] nums, int k) { int result = 0; for (int i = 0; i < nums.length; i++) { int total = 0; for (int j = i; j < nums.length; j++) { total += nums[j]; if (total == k) result++; } } return result; }}function subarraySum(nums, k) { let result = 0; for (let i = 0; i < nums.length; i++) { let total = 0; for (let j = i; j < nums.length; j++) { total += nums[j]; if (total === k) result++; } } return result;}impl Solution { pub fn subarray_sum(nums: Vec<i32>, k: i32) -> i32 { let mut result = 0; for i in 0..nums.len() { let mut total = 0; for j in i..nums.len() { total += nums[j]; if total == k { result += 1; } } } result }}func subarraySum(nums []int, k int) int { result := 0 for i := 0; i < len(nums); i++ { total := 0 for j := i; j < len(nums); j++ { total += nums[j] if total == k { result++ } } } return result}Approach 3: Space-Optimized Variant
Section titled “Approach 3: Space-Optimized Variant”A third approach demonstrating an alternative technique for solving this problem. This implementation optimizes either time or space complexity compared to the previous approaches.
Pseudocode
Section titled “Pseudocode”function approach3(): // Implementation approach goes hereSolution Code
Section titled “Solution Code”"""Solution for Subarray Sum Equals K"""
def solve(): """Implementation for approach 3 of Subarray Sum Equals K""" pass
if __name__ == "__main__": print("Solution ready")#include <bits/stdc++.h>using namespace std;
// Solution for Subarray Sum Equals K// Approach 3: Implementation
int main() {{ // Main implementation goes here return 0;}}/** * Solution for Subarray Sum Equals K * Approach 3 */public class SubarraySumEqualsKSpaceOptimized {{
public static void main(String[] args) {{ // Implementation goes here }}}}/** * Solution for Subarray Sum Equals K * Approach 3 */
function solve() {{ // Implementation goes here}}
module.exports = solve;/// Solution for Subarray Sum Equals K/// Approach 3
fn main() {{ println!("Solution implementation");}}package main
import "fmt"
// Solution for Subarray Sum Equals K// Approach 3
func main() {{ fmt.Println("Solution implementation")}}