mirror of
https://github.com/TheAlgorithms/Java.git
synced 2026-03-13 08:40:43 +08:00
add Subarray Sum Equals K using prefix sum (#7252)
Co-authored-by: Deniz Altunkapan <deniz.altunkapan@outlook.com>
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user