Here is the problem statement:
Given an expectedSum value find the sum (n+ (n+1) = expectedValue) from a list that equals the expectedSum. I am using the following list
1,3,4,4,5,9
and looking for the sum to be 8 (3+5, 4+4)
*Note the list is sorted
Solution 1:
Integer expectedSum = 8;
List<Integer> listInts = Arrays.asList(1,3,4,4,5,9);
for (Integer k=0; k<listInts.size();k++){
for (Integer j=k+1; j<listInts.size();j++){
if (listInts.get(k)+listInts.get(j)==expectedSum){
System.debug(listInts.get(k) + ' + ' + listInts.get(j));
}
}
}
The above time complexity for a nested for loop is O(n^2)
Solution 2:
Do a binary search to search if the diff is contained in the list
Integer expectedSum = 8;
List<Integer> listInts = Arrays.asList(1,3,4,4,5,9);
for (Integer listInt : listInts){
Integer diffInt = expectedSum-listInt;
if (binarySearch(listInts, diffInt)!=null){
System.debug(listInt + " + " + diffInt);
}
}
public static Integer binarySearch(List<Integer> listInts, Integer searchInt){
Integer startPos = 0;
Integer listSize = listInts.size() - 1;
Integer mid;
while(startPos <= listSize){
mid=(startPos+listSize)/2;
if(listInts.get(mid) == searchInt){
return listInts.get(mid);
}
else if(searchInt < listInts.get(mid)){
listSize = mid - 1;
}
else{
startPos = mid + 1;
}
}
return null;
}
the above time complexity for binary search is for each element in the array O(n log n) Returning null is not a good practice try to return another number or throw an exception.
Solution 3:
Check if the diff is contained in the list by using the .contains method
Integer expectedSum = 8;
List<Integer> listInts = Arrays.asList(1,3,4,4,5,9);
for (Integer listInt : listInts){
Integer diffInt =expectedSum-listInt;
if (listInts.contains(diffInt)){
System.debug(listInt + ' + ' + diffInt);
}
}
the above time complexity for loop is O(n)
Option 4
Start on either end of the array and move inwards when you find a solution, if the sum of the outer and inner element is bigger that the expectedSum move the maxPointer inwards, if it is smaller move the minPointer inwards.
Integer expectedSum = 1;
List<Integer> listInts = Arrays.asList(1,3,4,4,5,9);
Integer maxPointer = listInts.size()-1;
Integer minPointer = 0;
for (Integer k=0; k<listInts.size();k++){
if (expectedSum < listInts.get(maxPointer)){
maxPointer-=1;
} else if (minPointer!=maxPointer){
Integer sumPair =listInts.get(minPointer) + listInts.get(maxPointer);
if ( sumPair == expectedSum){
System.debug(listInts.get(minPointer) + " + " + listInts.get(maxPointer));
minPointer +=1;
maxPointer-=1;
} else if (sumPair < expectedSum){
minPointer +=1;
} else {
maxPointer-=1;;
}
}
}
the above time complexity for loop is O(n)
Output:
4 + 4 5 + 3 3 + 5
Bonus:
How to do it with an unsorted list:
Iterate through the list and add the integer to the list, if the diff of the expected sum and integer is contained in the set then print it
Integer expectedSum = 8;
List<Integer> listInts = Arrays.asList(7,4,6,1,5,2,3);
Set<Integer> intSetWithDiff = new HashSet<>();
for (Integer listInt : listInts){
Integer sumDiff = expectedSum - listInt;
if (intSetWithDiff.contains(sumDiff)){
System.debug(listInt + " + " + sumDiff);
}
intSetWithDiff.add(listInt);
}
Output:
1 + 7 2 + 6 3 + 5