Find subarrays with given sum in an array
Naive Method:
The basic brute force approach to this problem would be generating all the subarrays of the given array, then looping through the generated subarray and calculating the sum and if this sum is equal to the given sum then printing this subarray as it is part of our solution.
public class Main {
public static void main(String[] args) {
int[] arr = {1, 4, 20, 3, 10, 5};
int targetSum = 33;
findSubArrays(arr, target);
}
public static void findSubArrays(int[] arr, int target) {
for (int start = 0; start < arr.length; start++) {
// initialize the sum of the current subarray to 0.
int currSum = 0;
for (int end = start; end < arr.length; end++) {
// add every element of the current subarray
// to the current running sum.
currSum += arr[end];
// print the starting and ending indices once we get
// subarray with given sum
if (currSum == target) {
System.out.println("starting index : " +
start + ", " + "Ending index : " + end);
}
}
}
}
}
Efficient Approach:
We can maintain two pointers, start
and end
pointers which represents a subarray and also we have to take a variable that stores the current sum
of the subarray starting from the start pointer and ending at the end pointer
package com.shohan;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int[] arr = {1, 4, 20, 3, 10, 5};
int targetSum = 33;
findSubArrays(arr, targetSum);
}
public static void findSubArrays(int[] arr, int targetSum) {
// Edge case: empty array
if (arr.length == 0) {
return;
}
// Initialize variables to keep track of the current sum and window boundaries
int currentSum = 0;
int start = 0;
int end = 0;
// Keep expanding the window until the end of the array is reached
while (end < arr.length) {
// If the sum is less than the target sum, add the next element to the window
if (currentSum < targetSum) {
currentSum += arr[end];
end++;
}
// If the sum is equal to the target sum, print the subarray
else if (currentSum == targetSum) {
printSubArray(arr, start, end);
// Shrink the window by removing the first element
currentSum -= arr[start];
start++;
}
// If the sum is greater than the target sum, shrink the window by removing the first element
else {
currentSum -= arr[start];
start++;
}
}
}
// Helper method to print a subArray
public static void printSubArray(int[] arr, int start, int end) {
System.out.println(Arrays.toString(Arrays.copyOfRange(arr, start, end)));
}
}
An efficient approach to finding subarrays with a given sum in an array is to use a HashMap to store the cumulative sum of the elements and their corresponding indices. Here's how it works:
Initialize a variable
sum_so_far
to 0 and a HashMapmap
to store the cumulative sum of the elements and their corresponding indices.Iterate through the array, for each element, add it to the
sum_so_far
and check ifsum_so_far - given_sum
already exists in the HashMap.If it exists, it means that there is a subarray with the given sum between the index in the HashMap and the current index.
If it doesn't exist, add the
sum_so_far
to the HashMap with the current index.Repeat steps 2-4 until the end of the array is reached
int[] arr = {1, 4, 20, 3, 10, 5};
int sum = 33;
int n = arr.length;
int sum_so_far = 0;
HashMap<Integer, Integer> map = new HashMap<>();
map.put(0, -1);
for (int i = 0; i < n; i++) {
sum_so_far += arr[i];
if (map.containsKey(sum_so_far - sum)) {
int start = map.get(sum_so_far - sum) + 1;
int end = i;
System.out.println("Subarray found from index " + start + " to " + end);
}
if (!map.containsKey(sum_so_far)) {
map.put(sum_so_far, i);
}
}
In this approach, we have one loop which runs n times. The time complexity is O(n) and space complexity is O(n) in the worst case, where all elements in the array are distinct. This approach is more efficient than the previous approaches because it only needs to iterate through the array once and it uses a HashMap to store the cumulative sum of the elements and their corresponding indices, so it doesn't need to generate all possible subarrays.