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}
Working JAVA Code
---------------------------
import java.util.Comparator;
public class Index implements Comparable{
Integer start;
Integer end;
public Integer getStart() {
return start;
}
public void setStart(Integer start) {
this.start = start;
}
public Integer getEnd() {
return end;
}
public void setEnd(Integer end) {
this.end = end;
}
public int compareTo(Object index1) {
index1 = (Index) index1;
Index index2 = (Index) this;
Integer index1Distance = ((Index) index1).getEnd().intValue() - ((Index) index1).getStart().intValue();
Integer index2Distance = ((Index) index2).getEnd().intValue() - ((Index) index2).getStart().intValue();
if (index1Distance > index2Distance)
return 1;
else if (index1Distance == index2Distance)
return 0;
else
return -1;
}
}
import java.util.HashMap;
import java.util.Map;
public class SubarraywithSumZero {
public Index findLongestSubArraywithSumZero(long[] inputArray) {
// 1. Generate a cummulative array
for (int i=1; i < inputArray.length; i++) {
inputArray[i] += inputArray[ (i-1)];
}
//2. Read the array, store it in map
// For a subraary with 0 there should + and - numbers
// we need to figure the longest distance indexes which have same numbers
// since our array is cummulative postives and negatives which sum to 0 will bring the
// intermittent array back to same number where it started
// eg intermittent array = -6, -8, -10, -6, -4, 1, 2, 3, 4, 1
// now from -6 we again reach -6
// and later from 1 back to 1 which implies these two arrays are summing to 0
// we just need the longest one
Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();
Index maxIndex = null;
for (int i=0; i < inputArray.length; i++) {
Integer index = new Integer(i);
Integer val = new Integer((int) inputArray[i]);
if (indexMap.get(val) == null) {
indexMap.put(val, index);
}
else {
if (maxIndex == null) {
maxIndex = new Index();
//collosion found the subarray
maxIndex.setStart(indexMap.get(val));
maxIndex.setEnd(new Integer(i));
}
else {
Index index1 = new Index();
index1.setStart(indexMap.get(val));
index1.setEnd(new Integer(i));
if (maxIndex.compareTo(index1) <= 0) {
maxIndex = index1;
}
}
}
}
return maxIndex;
}
public static void main(String[] args) {
long inputArray[] = {3,2,4,-6,-8,10,11};
SubarraywithSumZero subarraywithSumZero = new SubarraywithSumZero();
Index maxIndex = subarraywithSumZero.findLongestSubArraywithSumZero(inputArray);
System.out.println("Longgest Subarray with sum starts at [" + maxIndex.getStart() + " ] and ends at [" + maxIndex.getEnd() + "]");
}
}
Lets take input array as a[]={-3,2,4,-6,-8,10,11}
Working JAVA Code
---------------------------
import java.util.Comparator;
public class Index implements Comparable{
Integer start;
Integer end;
public Integer getStart() {
return start;
}
public void setStart(Integer start) {
this.start = start;
}
public Integer getEnd() {
return end;
}
public void setEnd(Integer end) {
this.end = end;
}
public int compareTo(Object index1) {
index1 = (Index) index1;
Index index2 = (Index) this;
Integer index1Distance = ((Index) index1).getEnd().intValue() - ((Index) index1).getStart().intValue();
Integer index2Distance = ((Index) index2).getEnd().intValue() - ((Index) index2).getStart().intValue();
if (index1Distance > index2Distance)
return 1;
else if (index1Distance == index2Distance)
return 0;
else
return -1;
}
}
import java.util.Map;
public class SubarraywithSumZero {
public Index findLongestSubArraywithSumZero(long[] inputArray) {
// 1. Generate a cummulative array
for (int i=1; i < inputArray.length; i++) {
inputArray[i] += inputArray[ (i-1)];
}
//2. Read the array, store it in map
// For a subraary with 0 there should + and - numbers
// we need to figure the longest distance indexes which have same numbers
// since our array is cummulative postives and negatives which sum to 0 will bring the
// intermittent array back to same number where it started
// eg intermittent array = -6, -8, -10, -6, -4, 1, 2, 3, 4, 1
// now from -6 we again reach -6
// and later from 1 back to 1 which implies these two arrays are summing to 0
// we just need the longest one
Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();
Index maxIndex = null;
for (int i=0; i < inputArray.length; i++) {
Integer index = new Integer(i);
Integer val = new Integer((int) inputArray[i]);
if (indexMap.get(val) == null) {
indexMap.put(val, index);
}
else {
if (maxIndex == null) {
maxIndex = new Index();
//collosion found the subarray
maxIndex.setStart(indexMap.get(val));
maxIndex.setEnd(new Integer(i));
}
else {
Index index1 = new Index();
index1.setStart(indexMap.get(val));
index1.setEnd(new Integer(i));
if (maxIndex.compareTo(index1) <= 0) {
maxIndex = index1;
}
}
}
}
return maxIndex;
}
public static void main(String[] args) {
long inputArray[] = {3,2,4,-6,-8,10,11};
SubarraywithSumZero subarraywithSumZero = new SubarraywithSumZero();
Index maxIndex = subarraywithSumZero.findLongestSubArraywithSumZero(inputArray);
System.out.println("Longgest Subarray with sum starts at [" + maxIndex.getStart() + " ] and ends at [" + maxIndex.getEnd() + "]");
}
}
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi Inder,
ReplyDeleteIn the above solution one corner case might be missing. If the first 5 elements of the array forms the largest sub sequence, example,
long inputArray[] = { 3, -2, 4, -5, -8, 10, 2, 4, 5, 6, 7 };
In this array the longest sub sequence that sum up to 0 is [3, -2, 4, -5]
In the cumulative array the 4th element would be 0. As the Map does not have a entry with key 0, code would miss the first occurrence. You may initialize the
indexMap with initial key value pairs,
Integer k0 = new Integer(0);
Integer v0 = new Integer(0);
Thanks,
Gautam
The output from your program is :
ReplyDeleteLonggest Subarray with sum starts at [0 ] and ends at [3]
how the hell do u get the above solution with your input array:{ 3, 2, 4, -6, -8, 10, 11 }
The correct solution should be from index 2 to index 5.
Can't you even check your program whether its giving correct answer or not.
Please dont publish any unchecked code over here as it leads to unnecessary wastage of time.