Skip to content

Commit 3e36833

Browse files
add Subarray Sum Equals K using prefix sum (#7252)
Co-authored-by: Deniz Altunkapan <deniz.altunkapan@outlook.com>
1 parent dfaa495 commit 3e36833

File tree

2 files changed

+131
-0
lines changed

2 files changed

+131
-0
lines changed
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package com.thealgorithms.prefixsum;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
6+
/**
7+
* Implements an algorithm to count the number of continuous subarrays
8+
* whose sum equals a given value k.
9+
*
10+
* <p>
11+
* This algorithm uses the Prefix Sum technique combined with a HashMap
12+
* to achieve O(N) time complexity.
13+
* </p>
14+
*
15+
* <p>
16+
* Let prefixSum[i] be the sum of elements from index 0 to i.
17+
* A subarray (j + 1) to i has sum k if:
18+
*
19+
* <pre>
20+
* prefixSum[i] - prefixSum[j] = k
21+
* </pre>
22+
* </p>
23+
*
24+
* <p>
25+
* The HashMap stores the frequency of each prefix sum encountered so far.
26+
* </p>
27+
*
28+
* <p>
29+
* <strong>Time Complexity:</strong> O(N)<br>
30+
* <strong>Space Complexity:</strong> O(N)
31+
* </p>
32+
*
33+
* @see <a href="https://en.wikipedia.org/wiki/Prefix_sum">Prefix Sum (Wikipedia)</a>
34+
* @author Ruturaj Jadhav, <a href="https://github.com/ruturajjadhav07">ruturajjadhav07</a>
35+
*/
36+
public final class SubarraySumEqualsK {
37+
38+
private SubarraySumEqualsK() {
39+
// Utility class; prevent instantiation
40+
}
41+
42+
/**
43+
* Counts the number of subarrays whose sum equals k.
44+
*
45+
* @param nums The input integer array.
46+
* @param k The target sum.
47+
* @return The number of continuous subarrays summing to k.
48+
* @throws IllegalArgumentException if nums is null.
49+
*/
50+
public static int countSubarrays(int[] nums, int k) {
51+
if (nums == null) {
52+
throw new IllegalArgumentException("Input array cannot be null");
53+
}
54+
55+
Map<Long, Integer> prefixSumFrequency = new HashMap<>();
56+
prefixSumFrequency.put(0L, 1);
57+
58+
long prefixSum = 0;
59+
int count = 0;
60+
61+
for (int num : nums) {
62+
prefixSum += num;
63+
64+
long requiredSum = prefixSum - k;
65+
count += prefixSumFrequency.getOrDefault(requiredSum, 0);
66+
67+
prefixSumFrequency.put(prefixSum, prefixSumFrequency.getOrDefault(prefixSum, 0) + 1);
68+
}
69+
70+
return count;
71+
}
72+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.thealgorithms.prefixsum;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertThrows;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
/**
9+
* Tests for {@link SubarraySumEqualsK}.
10+
*/
11+
class SubarraySumEqualsKTest {
12+
13+
@Test
14+
void testBasicExample() {
15+
int[] nums = {1, 1, 1};
16+
int k = 2;
17+
assertEquals(2, SubarraySumEqualsK.countSubarrays(nums, k));
18+
}
19+
20+
@Test
21+
void testWithNegativeNumbers() {
22+
int[] nums = {1, -1, 0};
23+
int k = 0;
24+
assertEquals(3, SubarraySumEqualsK.countSubarrays(nums, k));
25+
}
26+
27+
@Test
28+
void testSingleElementEqualToK() {
29+
int[] nums = {5};
30+
int k = 5;
31+
assertEquals(1, SubarraySumEqualsK.countSubarrays(nums, k));
32+
}
33+
34+
@Test
35+
void testSingleElementNotEqualToK() {
36+
int[] nums = {5};
37+
int k = 3;
38+
assertEquals(0, SubarraySumEqualsK.countSubarrays(nums, k));
39+
}
40+
41+
@Test
42+
void testAllZeros() {
43+
int[] nums = {0, 0, 0};
44+
int k = 0;
45+
assertEquals(6, SubarraySumEqualsK.countSubarrays(nums, k));
46+
}
47+
48+
@Test
49+
void testEmptyArray() {
50+
int[] nums = {};
51+
int k = 0;
52+
assertEquals(0, SubarraySumEqualsK.countSubarrays(nums, k));
53+
}
54+
55+
@Test
56+
void testNullArrayThrowsException() {
57+
assertThrows(IllegalArgumentException.class, () -> SubarraySumEqualsK.countSubarrays(null, 0));
58+
}
59+
}

0 commit comments

Comments
 (0)