Code Posted at ->

Working Java code for each of these puzzles available at http://datastructure-puzzles-codesolutions.blogspot.com


Code Downloads from github https://github.com/inders/datastructure-repo

Tuesday, November 2, 2010

an array contain +ve and -ve element, find subarray whose sum =0;

an array contain +ve and -ve element, find subarray whose sum =0;

Lets take input array as a[]={-3,2,4,-6,-8,10,11}
https://github.com/inders/datastructure-repo/tree/master/subarraywithsumzero/src

Working JAVA Code is here
GITHUB Working Java Code
Algorithm/Approach is here


How to think Approach
Since it's easier to think pictorial imagine the cummulative sumarry of the original array in a X-Y corrdinate and you'll see if there are negative/postive numbers negating each others within a region your graph would go up/down and reach the same point after a while. So essentially you could have nested subarray as seen above in the smaller RED line. Non overlapping such subarrays seen with the right side RED line. You are interested in the longest RED line.

Approach

1. Store the sum of elements till that element in a separate array
2. w.r.t to example in question our interim subarray would like
-3, -1, 3, -3, -11, -1, 10

3. looking at the interim array you can observe a pattern that if an element summed upto -3 at any index and there is another -3 at a further index ( Since this being a cummulative summation array wherein the summation started at -3 and then again went up and down and back to -3) These two indexes have elements which are negating each other completely and is one of the resultant set. You need to skip the element at head index as that has contribution from previous summation also.

You can achieve the above by putting the indexes in a hash map and check for collision's and use the start index and the current index as a resultant set.

So in out interim array
-3, -1, 3, -3, -11, -1, 10

-1, 3, -3 is one set and input elements = { 2, 4, -6}
3, -3, -11, -1 is another and input elements = { 4, -6, -8, 10}

2 comments:

Inder said...

one way is to brute force go and find all possible nCk and the one's that are summing to 0 are the resultant set.

Can we optimize it using some sort of dynamic programming. Looking for overlapping sub-problems you'll find that you don't need to check for summation of all elements in the array till that element again and again you could use memonization to make it linear.

Approach

1. Store the sum of elements till that element in a separate array
2. w.r.t to example in question our interim subarray would like
-3, -1, 3, -3, -11, -1, 10

3. looking at the interim array you can observe a pattern that if an element summed upto -3 at any index and there is another -3 at a further index ( Since this being a cummulative summation array wherein the summation started at -3 and then again went up and down and back to -3) These two indexes have elements which are negating each other completely and is one of the resultant set. You need to skip the element at head index as that has contribution from previous summation also.

You can achieve the above by putting the indexes in a hash map and check for collision's and use the start index and the current index as a resultant set.

So in out interim array
-3, -1, 3, -3, -11, -1, 10

-1, 3, -3 is one set and input elements = { 2, 4, -6}
3, -3, -11, -1 is another and input elements = { 4, -6, -8, 10}

Aravind said...

I think, this problem and its solution is similiar to the problem of computing maximum substring with equal number of 0s and 1s.