Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package com.thealgorithms.prefixsum;

import java.util.HashMap;
import java.util.Map;

/**
* Implements an algorithm to count the number of continuous subarrays
* whose sum equals a given value k.
*
* <p>
* This algorithm uses the Prefix Sum technique combined with a HashMap
* to achieve O(N) time complexity.
* </p>
*
* <p>
* Let prefixSum[i] be the sum of elements from index 0 to i.
* A subarray (j + 1) to i has sum k if:
*
* <pre>
* prefixSum[i] - prefixSum[j] = k
* </pre>
* </p>
*
* <p>
* The HashMap stores the frequency of each prefix sum encountered so far.
* </p>
*
* <p>
* <strong>Time Complexity:</strong> O(N)<br>
* <strong>Space Complexity:</strong> O(N)
* </p>
*
* @see <a href="https://en.wikipedia.org/wiki/Prefix_sum">Prefix Sum (Wikipedia)</a>
* @author Ruturaj Jadhav, <a href="https://github.com/ruturajjadhav07">ruturajjadhav07</a>
*/
public final class SubarraySumEqualsK {

private SubarraySumEqualsK() {
// Utility class; prevent instantiation
}

/**
* Counts the number of subarrays whose sum equals k.
*
* @param nums The input integer array.
* @param k The target sum.
* @return The number of continuous subarrays summing to k.
* @throws IllegalArgumentException if nums is null.
*/
public static int countSubarrays(int[] nums, int k) {
if (nums == null) {
throw new IllegalArgumentException("Input array cannot be null");
}

Map<Long, Integer> prefixSumFrequency = new HashMap<>();
prefixSumFrequency.put(0L, 1);

long prefixSum = 0;
int count = 0;

for (int num : nums) {
prefixSum += num;

long requiredSum = prefixSum - k;
count += prefixSumFrequency.getOrDefault(requiredSum, 0);

prefixSumFrequency.put(prefixSum, prefixSumFrequency.getOrDefault(prefixSum, 0) + 1);
}

return count;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.thealgorithms.prefixsum;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import org.junit.jupiter.api.Test;

/**
* Tests for {@link SubarraySumEqualsK}.
*/
class SubarraySumEqualsKTest {

@Test
void testBasicExample() {
int[] nums = {1, 1, 1};
int k = 2;
assertEquals(2, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testWithNegativeNumbers() {
int[] nums = {1, -1, 0};
int k = 0;
assertEquals(3, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testSingleElementEqualToK() {
int[] nums = {5};
int k = 5;
assertEquals(1, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testSingleElementNotEqualToK() {
int[] nums = {5};
int k = 3;
assertEquals(0, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testAllZeros() {
int[] nums = {0, 0, 0};
int k = 0;
assertEquals(6, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testEmptyArray() {
int[] nums = {};
int k = 0;
assertEquals(0, SubarraySumEqualsK.countSubarrays(nums, k));
}

@Test
void testNullArrayThrowsException() {
assertThrows(IllegalArgumentException.class, () -> SubarraySumEqualsK.countSubarrays(null, 0));
}
}
Loading