Prefix Sum and Sliding Window 02
Given an array of positive and negative numbers. Find if there is a subarray(of at-least one) with 0 sum.
Problem link :- click here
Code
import java.util.HashSet;
import java.util.Scanner;
import java.util.Set;
// CHECK IF THERE IS A SUBARRAY WITH 0 SUM
public class Prefix_sum__Sliding_window_02
{
static boolean containsSubarrayWith0sum(int[] arr, int n)
{
// Calculating prefix sum array(psa)
int[] psa = new int[n];
psa[0] = arr[0];
for(int i=1; i<n; i++)
psa[i] = psa[i-1] + arr[i];
/*
LOGIC: -
*) In `psa` we have sum of elements starting from index 0 to that index.
*) If any element in `psa` is == 0 then there is a sub-array starting from index 0
having sum of elements = 0
*) How to verify sub-arrays which doesn't start with index 0?
*) Consider a example : arr = {3, 4, -4, 7, 9}
psa = {3, 7, 3, 10, 19}
If we have a sub-array with sum 0, then the `psa` will have some elements repeated.
In this example psa[0] == psa[2]
psa[0] = psa[1] + arr[2]
psa[0] = psa[0] + arr[1] + arr[2]
which means arr[1] + arr[2] == 0.
*) So if we get any element in the `psa` twice, then there is a sub-array with sum 0
*/
for(int i=0; i<n; i++)
{
for(int j=i+1; j<n; j++)
{
if(psa[i] == psa[j])
return true;
}
}
return false;
}
static boolean containsSubarrayWith0sum2(int[] arr, int n)
{
Set<Integer> hs = new HashSet<Integer>();
/*
Here instead of storing the sum in `psa` we will store it in a hash set
so it will be easy to check if the sum is already stored in the hash set.
*/
Integer sum = 0;
for(int i=0; i<n; i++)
{
sum += arr[i];
if( arr[i]==0 || sum==0 || hs.contains(sum) )
return true;
hs.add(sum);
}
return false;
}
public static void main(String[] args)
{
Scanner s = new Scanner(System.in);
// Taking size of array and array as input from the user
System.out.print("Enter the size of the array : ");
int n = s.nextInt();
int[] arr = new int[n];
System.out.println("Enter the array elements : ");
for(int i=0; i<n; i++)
arr[i] = s.nextInt();
// Calculating prefix sum array(psa)
int[] psa = new int[n];
psa[0] = arr[0];
for(int i=1; i<n; i++)
psa[i] = psa[i-1] + arr[i];
boolean ans = containsSubarrayWith0sum(arr, n); //Time complexity: O(n^2)
boolean ans2 = containsSubarrayWith0sum2(arr, n); //Time complexity: O(n)
if(ans)
System.out.println("\n\nYES by first method");
if(ans2)
System.out.println("\nYES by second method");
}
}
Comments
Post a Comment