In this article, we will learn to resolve the Subarray Sum Equals K problems by using Brute force, Sliding window, and Hash table algorithms
Problem 1
Given an unsorted array of non-negative integers
a[n]
and an integerk
Find a continuous sub array whose sum equals to
k
Example 1.1
Input: a = [4, 0, 11, 6, 1, 7] and k = 8
Output: [1, 7]
Approach 1.1: Brute Force
Use 2 for-loop to consider the sum of every continuous subarray
Return the first subarray when its sum equals to
k
import java.util.Arrays;
public class SubarrayGivenSumBruteforce {
public static int[] findSubarray(int[] a, int k) {
for(int i = 0; i < a.length; i++) {
int currentSum = a[i];
for(int j = i + 1; j <= a.length; j++) {
if (currentSum == k) {
return Arrays.copyOfRange(a, i, j);
} else if (currentSum > k || j == a.length) {
break;
}
currentSum += a[j];
}
}
return null;
}
public static void main (String[] args) {
int[] a = {4, 0, 11, 6, 1, 7};
int k = 8;
System.out.println(Arrays.toString(findSubarray(a, k)));
}
}
Time complexity: O(n2) as with each element in the given array, we iterate over the remaining elements to calculate the sum of possible subarrays
Space complexity: O(1)
Approach 1.2: Sliding Window
Find the sliding window sum, say
ws
, in the index range[i, j]
of the given arraya[n]
, that equalsk
by increasingj
continuously fromi
ton-1
Return
ws
as soon as it equalsk
, otherwise, reducews
and increasei
import java.util.Arrays;
public class SubarrayGivenSumWindowSliding {
public static int[] findSubarray(int[] a, int k) {
int windowSum = 0, i = 0, j = 0;
while (i < a.length) {
while (j < a.length && windowSum < k) {
windowSum += a[j++];
}
if (windowSum == k) {
return Arrays.copyOfRange(a, i, j);
}
windowSum -= a[i++];
}
return null;
}
public static void main (String[] args) {
int[] a = {4, 0, 11, 6, 1, 7};
int k = 8;
System.out.println(Arrays.toString(findSubarray(a, k)));
}
}
Time complexity: O(n)
Space complexity: O(1)
Problem 2
Given an unsorted array of integers
a[n]
and an integerk
Find the total number of continuous subarrays whose sum equals to
k
Example 2.1
Input: a = [-4, 12, -11, 6, 1, 7], k = 8
Output: 3
Explanation: [-4, 12], [12, -11, 6, 1], [1, 7] are 3 subarrays have sum equals to 8
Example 2.2
Input: a = [0, 0, 0], k = 0
Output: 6
Explanation: There are three subarrays [0] at index 0, 1, and 2, two subarrays [0, 0] at index [0, 1] and [1, 2], and one subarray [0, 0, 0] have sum equals to 0
Approach 2: Hash table
Say ci and cj are the cumulative sums at index
i
andj
in the given arraya[n]
Elements from
i
toj
will form a subarray that satify the constraint if and only if cj - ci = k (∀ 0 <= i < j < n)At index
j
, there may have multiple subarrays satisfy the above constraint. To reserve the count value of them, we can use a hash table to store cj as key, and the count of the right subarrays untilj
(cj-k) as valueUse a variable
cumulativeCount
to track the cumulative count of all contiguous subarrays, every time we found a new right subarrayReturn
cumulativeCount
as the final result
import java.util.HashMap;
import java.util.Map;
public class SubarrayGivenSumHashtable {
public static int countSubArraysWithHashTable(int[] a, int k) {
int cumulativeCount = 0;
int cumulativeSum = 0;
Map<Integer, Integer> map = new HashMap<>();
map.put(0, 1);
for (int value : a) {
cumulativeSum += value;
if (map.containsKey(cumulativeSum - k)) {
cumulativeCount += map.get(cumulativeSum - k);
}
map.put(cumulativeSum, map.getOrDefault(cumulativeSum, 0) + 1);
}
return cumulativeCount;
}
public static void main (String[] args) {
int[] a = {-4, 12, -11, 6, 1, 7};
int k = 8;
System.out.println(countSubArraysWithHashTable(a, k));
int[] b = {0, 0, 0};
k = 0;
System.out.println(countSubArraysWithHashTable(b, k));
}
}
- Output
3
6
Time complexity: O(n) as the given array is traversed through only once
Space complexity: O(n) as the hash table can hold up to
n
elements