Binary TreesBinary Trees36

  1. 1Preorder Traversal of a Binary Tree using Recursion
  2. 2Preorder Traversal of a Binary Tree using Iteration
  3. 3Postorder Traversal of a Binary Tree Using Recursion
  4. 4Postorder Traversal of a Binary Tree using Iteration
  5. 5Level Order Traversal of a Binary Tree using Recursion
  6. 6Level Order Traversal of a Binary Tree using Iteration
  7. 7Reverse Level Order Traversal of a Binary Tree using Iteration
  8. 8Reverse Level Order Traversal of a Binary Tree using Recursion
  9. 9Find Height of a Binary Tree
  10. 10Find Diameter of a Binary Tree
  11. 11Find Mirror of a Binary Tree - Todo
  12. 12Inorder Traversal of a Binary Tree using Recursion
  13. 13Inorder Traversal of a Binary Tree using Iteration
  14. 14Left View of a Binary Tree
  15. 15Right View of a Binary Tree
  16. 16Top View of a Binary Tree
  17. 17Bottom View of a Binary Tree
  18. 18Zigzag Traversal of a Binary Tree
  19. 19Check if a Binary Tree is Balanced
  20. 20Diagonal Traversal of a Binary Tree
  21. 21Boundary Traversal of a Binary Tree
  22. 22Construct a Binary Tree from a String with Bracket Representation
  23. 23Convert a Binary Tree into a Doubly Linked List
  24. 24Convert a Binary Tree into a Sum Tree
  25. 25Find Minimum Swaps Required to Convert a Binary Tree into a BST
  26. 26Check if a Binary Tree is a Sum Tree
  27. 27Check if All Leaf Nodes are at the Same Level in a Binary Tree
  28. 28Lowest Common Ancestor (LCA) in a Binary Tree
  29. 29Solve the Tree Isomorphism Problem
  30. 30Check if a Binary Tree Contains Duplicate Subtrees of Size 2 or More
  31. 31Check if Two Binary Trees are Mirror Images
  32. 32Calculate the Sum of Nodes on the Longest Path from Root to Leaf in a Binary Tree
  33. 33Print All Paths in a Binary Tree with a Given Sum
  34. 34Find the Distance Between Two Nodes in a Binary Tree
  35. 35Find the kth Ancestor of a Node in a Binary Tree
  36. 36Find All Duplicate Subtrees in a Binary Tree

Count Subarrays with Given Sum using Prefix Sum and HashMap
Optimal Solution



Problem Statement

Given an integer array arr and a target sum k, your task is to find the total number of continuous subarrays whose elements add up to exactly k.

A subarray is a sequence of elements that appears in the same order in the array and is contiguous. The same element can be included in multiple subarrays if it appears in different positions.

This problem is common in applications involving range-based queries, financial analysis, and interval sum counting.

Examples

Input ArrayTarget Sum (k)Count of SubarraysDescription
[1, 2, 3]32Subarrays: [1, 2], [3]
[1, 1, 1]22Subarrays: [1, 1] (at two different positions)
[3, 4, 7, 2, -3, 1, 4, 2]74Subarrays: [3,4], [7], [4, 2, 1], [1, 4, 2]
[1, -1, 0]03Subarrays: [1, -1], [0], [1, -1, 0]
[]00Empty array has no subarrays
[0, 0, 0]06All possible subarrays (of lengths 1 to 3) sum to 0
[1, 2, 3]100No subarray adds up to 10
[5]51Single element equal to k
[5]30Single element not equal to k

Solution

To count how many subarrays sum to a given number k, we can use a clever technique based on prefix sums and a hash map to store frequency of those sums. This approach avoids nested loops and gives us a highly efficient solution with linear time complexity.

Understanding the Core Idea

Imagine you're scanning the array from left to right and keeping track of the sum of all elements you've seen so far. This is called the prefix sum. At any position i, the sum of the subarray from some previous position j to i is simply prefix[i] - prefix[j-1].

Now, if you know that prefix[i] - k has been seen before, that means there exists a subarray that ends at position i and adds up to k.

Different Cases to Consider

  • Exact match: If the current prefix sum is equal to k, it means the subarray starting from index 0 to current index forms a valid subarray.
  • Matching a previous prefix: If you've previously seen a prefix sum of curr_sum - k, it means all subarrays that end at the current index and start after those earlier indices add up to k. You can count how many times that prefix occurred and add that to your answer.
  • Negative numbers and zeroes: The method works even if the array has negative numbers or zeros. For example, in an array like [1, -1, 0] with k = 0, multiple combinations are valid.
  • Empty array: There are no subarrays to count, so the result is 0.
  • All zeros: In arrays like [0, 0, 0], every subarray (length 1 to full length) adds up to 0. This results in multiple overlapping subarrays that all qualify.

Why This Works

By storing how often each prefix sum has appeared, we avoid re-checking every possible subarray. We can just look up how many times we've seen prefix_sum - k in constant time using a hash map. This optimization turns a brute-force O(n²) approach into a fast O(n) solution.

This method is highly effective, scalable, and works for large arrays with positive, negative, or zero values.

Visualization

Algorithm Steps

  1. Given an array arr and a target k.
  2. Initialize a prefix sum curr_sum = 0 and a hash map prefix_count to store frequency of prefix sums.
  3. Initialize count = 0.
  4. Iterate through the array:
  5. → Add current element to curr_sum.
  6. → If curr_sum == k, increment count by 1.
  7. → If curr_sum - k exists in prefix_count, add its frequency to count.
  8. → Update the frequency of curr_sum in prefix_count.
  9. Return the total count.

Code

Python
JavaScript
Java
C++
C
from collections import defaultdict

def count_subarrays_with_sum(arr, k):
    prefix_count = defaultdict(int)
    curr_sum = 0
    count = 0

    for num in arr:
        curr_sum += num
        if curr_sum == k:
            count += 1
        if (curr_sum - k) in prefix_count:
            count += prefix_count[curr_sum - k]
        prefix_count[curr_sum] += 1

    return count

# Sample Input
arr = [1, 1, 1]
k = 2
print("Count of Subarrays:", count_subarrays_with_sum(arr, k))

Time Complexity

CaseTime ComplexityExplanation
Best CaseO(n)Each element is visited exactly once, and all operations (hashmap lookups and updates) take constant time.
Average CaseO(n)On average, the algorithm maintains a prefix sum hashmap and performs constant-time operations per element.
Average CaseO(n)Even in the worst case, the array is traversed only once and hashmap operations remain O(1), resulting in linear time complexity.

Space Complexity

O(n)

Explanation: A hashmap is used to store the frequency of prefix sums, which can grow up to the size of the input array in the worst case.



Welcome to ProgramGuru

Sign up to start your journey with us

Support ProgramGuru.org

You can support this website with a contribution of your choice.

When making a contribution, mention your name, and programguru.org in the message. Your name shall be displayed in the sponsors list.

PayPal

UPI

PhonePe QR

MALLIKARJUNA M