Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Subarray sum with at least two elements in JavaScript
We need to write a JavaScript function that takes an array of integers and a target value, then checks whether there exists a continuous subarray of size at least 2 that sums up to a multiple of the target value.
Problem Statement
Given an array of integers and a target value k, return true if there exists a continuous subarray of size at least 2 that sums up to n*k (where n is any integer), otherwise return false.
For example:
Input: arr = [23, 2, 6, 4, 7], target = 6 Output: true
The subarray [2, 6, 4, 7] has sum 19, but we need a sum that's a multiple of 6. However, [23, 2, 6, 4, 7] sums to 42, which is 7 × 6.
Approach: Prefix Sum with Hash Map
We use the mathematical property that if two prefix sums have the same remainder when divided by k, then the subarray between them has a sum divisible by k. We store remainders and their first occurrence indices in a hash map.
const arr = [23, 2, 6, 4, 7];
const target = 6;
const checkSubarraySum = (arr = [], target = 1) => {
if (arr.length < 2) return false;
let sum = 0;
const hash = {};
hash[0] = -1; // Handle case where prefix sum itself is divisible
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
if (target !== 0) {
sum %= target;
}
if (hash[sum] !== undefined) {
// Check if subarray length is at least 2
if (i - hash[sum] > 1) {
return true;
}
} else {
hash[sum] = i;
}
}
return false;
};
console.log(checkSubarraySum(arr, target));
true
Step-by-Step Explanation
Let's trace through the algorithm with our example:
// Trace: arr = [23, 2, 6, 4, 7], target = 6
const traceSubarraySum = (arr, target) => {
let sum = 0;
const hash = {0: -1};
console.log("Initial hash:", hash);
for (let i = 0; i < arr.length; i++) {
sum += arr[i];
const remainder = target !== 0 ? sum % target : sum;
console.log(`i=${i}, arr[i]=${arr[i]}, sum=${sum}, remainder=${remainder}`);
if (hash[remainder] !== undefined) {
const length = i - hash[remainder];
console.log(`Found matching remainder! Length: ${length}`);
if (length > 1) {
console.log(`Subarray found from index ${hash[remainder] + 1} to ${i}`);
return true;
}
} else {
hash[remainder] = i;
console.log("Updated hash:", hash);
}
}
return false;
};
traceSubarraySum([23, 2, 6, 4, 7], 6);
Initial hash: { '0': -1 }
i=0, arr[i]=23, sum=23, remainder=5
Updated hash: { '0': -1, '5': 0 }
i=1, arr[i]=2, sum=25, remainder=1
Updated hash: { '0': -1, '5': 0, '1': 1 }
i=2, arr[i]=6, sum=31, remainder=1
Found matching remainder! Length: 1
i=3, arr[i]=4, sum=35, remainder=5
Found matching remainder! Length: 3
Subarray found from index 1 to 3
Edge Cases
// Test edge cases
console.log("Edge case 1 - Array too small:");
console.log(checkSubarraySum([5], 6)); // false
console.log("\nEdge case 2 - Target is 0:");
console.log(checkSubarraySum([0, 0], 0)); // true
console.log("\nEdge case 3 - No valid subarray:");
console.log(checkSubarraySum([1, 2], 3)); // false
console.log("\nEdge case 4 - Valid subarray at end:");
console.log(checkSubarraySum([1, 5], 6)); // true
Edge case 1 - Array too small: false Edge case 2 - Target is 0: true Edge case 3 - No valid subarray: false Edge case 4 - Valid subarray at end: true
Time and Space Complexity
Time Complexity: O(n) where n is the length of the array, as we iterate through it once.
Space Complexity: O(min(n, k)) for the hash map storing remainders.
Conclusion
This algorithm efficiently finds subarrays with sums divisible by a target using prefix sums and modular arithmetic. The key insight is that identical remainders indicate a divisible subarray between those positions.
