Two Sum - Pair Closest to 0
Given an integer array arr[], the task is to find the maximum sum of two elements such that sum is closest to zero.
Note: In case if we have two of more ways to form sum of two elements closest to zero return the maximum sum.
Examples:
Input: arr[] = [-8, 5, 2, -6]
Output: -1
Explanation: The min absolute sum pair is (5, -6)Input: arr[] = [0, -8, -6, 3]
Output: 3
Explanation: We have a tie between (0, 3) and (-6, 3). We pick the max sum in this case which is 0+3Input: arr[] = [-7, 4, 1, -2]
Output: -1
Explanation: The min absolute sum pair is (4, -5).
[Naive Approach] Check Every Possible Pair - O(n^2) Time and O(1) Space
The idea is to use the naive method that checks the sum of every possible pair of elements in the array and keeps track of the pair with the minimum absolute sum.
// C++ Code for Two Sum - Closest Pair
// Using Naive Approach
#include <bits/stdc++.h>
using namespace std;
int minAbsSumPair(vector<int>& arr) {
// Initialize the result with the sum
// of the first two elements
int res = arr[0] + arr[1];
// Consider every pair, find its sum and
// update result if we get a smaller value
for (int i = 0; i < arr.size() - 1; i++) {
for (int j = i + 1; j < arr.size(); j++) {
int sum = arr[i] + arr[j];
if (abs(sum) < abs(res)) {
res = sum;
}
else if(abs(sum) == abs(res)) {
res = max(res, sum);
}
}
}
return res;
}
int main() {
vector<int> arr = { 0, -8, -6, 3 };
cout << minAbsSumPair(arr);
return 0;
}
// Java Code for Two Sum - Closest Pair
// Using Naive Approach
import java.util.*;
class GfG {
// Function to find the minimum absolute sum pair
static int minAbsSumPair(int[] arr) {
// Initialize the result with the sum
// of the first two elements
int res = arr[0] + arr[1];
// Consider every pair, find its sum and
// update result if we get a smaller value
for (int i = 0; i < arr.length - 1; i++) {
for (int j = i + 1; j < arr.length; j++) {
int sum = arr[i] + arr[j];
if (Math.abs(sum) < Math.abs(res)) {
res = sum;
}
else if (Math.abs(sum) == Math.abs(res)) {
res = Math.max(res, sum);
}
}
}
return res;
}
public static void main(String[] args) {
int[] arr = { 0, -8, -6, 3 };
System.out.println(minAbsSumPair(arr));
}
}
# Python Code for Two Sum - Closest Pair
# Using Naive Approach
# Function to find the minimum absolute sum pair
def minAbsSumPair(arr):
# Initialize the result with the sum
# of the first two elements
res = arr[0] + arr[1]
# Consider every pair, find its sum and
# update result if we get a smaller value
for i in range(len(arr) - 1):
for j in range(i + 1, len(arr)):
sum = arr[i] + arr[j]
if abs(sum) < abs(res):
res = sum
elif abs(sum) == abs(res):
res = max(res, sum)
return res
if __name__ == "__main__":
arr = [0, -8, -6, 3]
print(minAbsSumPair(arr))
// C# Code for Two Sum - Closest Pair
// Using Naive Approach
using System;
class GfG {
// Function to find the minimum absolute sum pair
public static int minAbsSumPair(int[] arr) {
// Initialize the result with the sum
// of the first two elements
int res = arr[0] + arr[1];
// Consider every pair, find its sum and
// update result if we get a smaller value
for (int i = 0; i < arr.Length - 1; i++) {
for (int j = i + 1; j < arr.Length; j++) {
int sum = arr[i] + arr[j];
if (Math.Abs(sum) < Math.Abs(res)) {
res = sum;
}
else if (Math.Abs(sum) == Math.Abs(res)) {
res = Math.Max(res, sum);
}
}
}
return res;
}
public static void Main(string[] args) {
int[] arr = { 0, -8, -6, 3 };
Console.WriteLine(minAbsSumPair(arr));
}
}
// Javascript Code for Two Sum - Closest Pair
// Using Naive Approach
// Function to find the minimum absolute sum pair
function minAbsSumPair(arr) {
// Initialize the result with the sum
// of the first two elements
let res = arr[0] + arr[1];
// Consider every pair, find its sum and
// update result if we get a smaller value
for (let i = 0; i < arr.length - 1; i++) {
for (let j = i + 1; j < arr.length; j++) {
let sum = arr[i] + arr[j];
if (Math.abs(sum) < Math.abs(res)) {
res = sum;
}
else if (Math.abs(sum) == Math.abs(res)) {
res = Math.max(res, sum);
}
}
}
return res;
}
let arr = [0, -8, -6, 3];
console.log(minAbsSumPair(arr));
Output
3
[Better Approach] Using Sorting + Binary Search - O(nlog(n)) Time and O(1) Space
The idea is to find the pair whose sum is closest to zero by sorting the array and using binary search for efficient lookup. For each element, we search for its closest complement using binary search, updating the closest sum found so far. If an exact zero sum is found, we return immediately.
Steps to implement the above idea:
- Sort the array to enable binary search.
- Iterate through each element and fix it as the first element of the pair.
- Use binary search to find the closest second element.
- Update the closest sum if the current pair gives a smaller absolute sum.
- Return 0 if an exact zero sum pair is found.
- Return the closest sum after checking all pairs.
// C++ Code for Two Sum - Closest Pair
// Using Binary Search
#include <bits/stdc++.h>
using namespace std;
int minAbsSumPair(vector<int>& arr) {
sort(arr.begin(), arr.end());
int n = arr.size();
// Variable to store the closest sum
int res = INT_MAX;
// Iterate over the array
for (int i = 0; i < n; i++) {
// Consider current element as first
// element of the pair and find the
// other element using binary search
int x = arr[i];
int left = i + 1, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
int curr = arr[mid] + x;
// If exact pair is found
if (curr == 0) {
return 0;
}
// Update res if the current pair is closer
if (abs(curr) < abs(res)) {
res = curr;
}
else if(abs(curr) == abs(res)) {
res = max(res, curr);
}
// If current is smaller than 0,
// go to right side. Else on the
// left side.
if (curr < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return res;
}
int main() {
vector<int> arr = { 0, -8, -6, 3 };
cout << minAbsSumPair(arr);
return 0;
}
// Java Code for Two Sum - Closest Pair
// Using Binary Search
import java.util.*;
class GfG {
static int minAbsSumPair(int[] arr) {
Arrays.sort(arr);
int n = arr.length;
// Variable to store the closest sum
int res = Integer.MAX_VALUE;
// Iterate over the array
for (int i = 0; i < n; i++) {
// Consider current element as first
// element of the pair and find the
// other element using binary search
int x = arr[i];
int left = i + 1, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
int curr = arr[mid] + x;
// If exact pair is found
if (curr == 0) {
return 0;
}
// Update res if the current pair is closer
if (Math.abs(curr) < Math.abs(res)) {
res = curr;
}
else if (Math.abs(curr) == Math.abs(res)) {
res = Math.max(res, curr);
}
// If current is smaller than 0,
// go to right side. Else on the
// left side.
if (curr < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return res;
}
public static void main(String[] args) {
int[] arr = { 0, -8, -6, 3 };
System.out.println(minAbsSumPair(arr));
}
}
# Python Code for Two Sum - Closest Pair
# Using Binary Search
# Function to find the minimum absolute sum pair
def minAbsSumPair(arr):
arr.sort()
n = len(arr)
# Variable to store the closest sum
res = float('inf')
# Iterate over the array
for i in range(n):
# Consider current element as first
# element of the pair and find the
# other element using binary search
x = arr[i]
left, right = i + 1, n - 1
while left <= right:
mid = (left + right) // 2
curr = arr[mid] + x
# If exact pair is found
if curr == 0:
return 0
# Update res if the current pair is closer
if abs(curr) < abs(res):
res = curr
elif abs(curr) == abs(res):
res = max(res, curr)
# If current is smaller than 0,
# go to right side. Else on the
# left side.
if curr < 0:
left = mid + 1
else:
right = mid - 1
return res
if __name__ == "__main__":
arr = [0, -8, -6, 3]
print(minAbsSumPair(arr))
// C# Code for Two Sum - Closest Pair
// Using Binary Search
using System;
class GfG {
public static int minAbsSumPair(int[] arr) {
Array.Sort(arr);
int n = arr.Length;
// Variable to store the closest sum
int res = int.MaxValue;
// Iterate over the array
for (int i = 0; i < n; i++) {
// Consider current element as first
// element of the pair and find the
// other element using binary search
int x = arr[i];
int left = i + 1, right = n - 1;
while (left <= right) {
int mid = (left + right) / 2;
int curr = arr[mid] + x;
// If exact pair is found
if (curr == 0) {
return 0;
}
// Update res if the current pair is closer
if (Math.Abs(curr) < Math.Abs(res)) {
res = curr;
}
else if (Math.Abs(curr) == Math.Abs(res)) {
res = Math.Max(res, curr);
}
// If current is smaller than 0,
// go to right side. Else on the
// left side.
if (curr < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return res;
}
public static void Main(string[] args) {
int[] arr = { 0, -8, -6, 3 };
Console.WriteLine(minAbsSumPair(arr));
}
}
// Javascript Code for Two Sum - Closest Pair
// Using Binary Search
// Function to find the minimum absolute sum pair
function minAbsSumPair(arr) {
arr.sort((a, b) => a - b);
let n = arr.length;
// Variable to store the closest sum
let res = Number.MAX_SAFE_INTEGER;
// Iterate over the array
for (let i = 0; i < n; i++) {
// Consider current element as first
// element of the pair and find the
// other element using binary search
let x = arr[i];
let left = i + 1, right = n - 1;
while (left <= right) {
let mid = Math.floor((left + right) / 2);
let curr = arr[mid] + x;
// If exact pair is found
if (curr === 0) {
return 0;
}
// Update res if the current pair is closer
if (Math.abs(curr) < Math.abs(res)) {
res = curr;
}
else if (Math.abs(curr) === Math.abs(res)) {
res = Math.max(res, curr);
}
// If current is smaller than 0,
// go to right side. Else on the
// left side.
if (curr < 0) {
left = mid + 1;
} else {
right = mid - 1;
}
}
}
return res;
}
let arr = [0, -8, -6, 3];
console.log(minAbsSumPair(arr));
Output
3
[Expected Approach] Using Sorting + Two Pointer - O(nlog(n)) Time and O(1) Space
The idea is to sort the array first and use two pointers, one at the leftmost (smallest) and the other at the rightmost (largest) element. We calculate their sum and check if it's closer to zero than our current best sum. If we find a sum of zero, we return immediately. Otherwise, we adjust the pointers based on whether the sum is positive (move right pointer left) or negative (move left pointer right).
Steps to implement the above idea:
- Sort the array in ascending order.
- Initialize two pointers: one at the start and one at the end.
- Initialize variables to store the closest sum and its absolute difference.
- Iterate while left pointer is less than right pointer.
- Update the closest sum if the current sum is closer to zero.
- Move the left pointer right if the sum is negative; else, move the right pointer left.
// C++ Code for Two Sum - Closest Pair
// Using Two Pointer
#include <bits/stdc++.h>
using namespace std;
int minAbsSumPair(vector<int>& arr) {
// Sorting the vector in ascending order
sort(arr.begin(), arr.end());
int i = 0, j = arr.size() - 1;
// Initializing sum with the first
// and last elements
int sum = arr[i] + arr[j];
// Initializing the result with
// the absolute value of the initial sum
int diff = abs(sum);
while (i < j) {
// If we have zero sum, there's no
// result better. Hence, we return
if (arr[i] + arr[j] == 0)
return 0;
// If we get a better result, we update the difference
if (abs(arr[i] + arr[j]) < abs(diff)) {
diff = abs(arr[i] + arr[j]);
sum = arr[i] + arr[j];
} else if (abs(arr[i] + arr[j]) == abs(diff)) {
// If there are multiple pairs with the
// same minimum absolute difference,
// return the pair with the larger sum
sum = max(sum, arr[i] + arr[j]);
}
// If the current sum is greater than
// zero, we search for a smaller sum
if (arr[i] + arr[j] > 0)
j--;
// Else, we search for a larger sum
else
i++;
}
return sum;
}
// Driver Code
int main() {
vector<int> arr = { 0, -8, -6, 3 };
cout << minAbsSumPair(arr) << endl;
return 0;
}
// Java Code for Two Sum - Closest Pair
// Using Two Pointer
import java.util.Arrays;
public class GfG {
public static int minAbsSumPair(int[] arr)
{
// Sorting the array in ascending order
Arrays.sort(arr);
int i = 0, j = arr.length - 1;
// Initializing sum with the first and last elements
int sum = arr[i] + arr[j];
// Initializing the result with the absolute value
// of the initial sum
int diff = Math.abs(sum);
while (i < j) {
// If we have zero sum, there's no result
// better. Hence, we return 0.
if (arr[i] + arr[j] == 0)
return 0;
// If we get a better result, we update the
// difference
if (Math.abs(arr[i] + arr[j])
< Math.abs(diff)) {
diff = (arr[i] + arr[j]);
sum = arr[i] + arr[j];
}
else if (Math.abs(arr[i] + arr[j])
== Math.abs(diff)) {
// If there are multiple pairs with the same
// minimum absolute difference, return the
// pair with the larger sum
sum = Math.max(sum, arr[i] + arr[j]);
}
// If the current sum is greater than zero, we
// search for a smaller sum
if (arr[i] + arr[j] > 0)
j--;
// Else, we search for a larger sum
else
i++;
}
return sum;
}
// Driver Code
public static void main(String[] args)
{
int[] arr = { 0, -8, -6, 3 };
System.out.println(minAbsSumPair(arr));
}
}
# Python Code for Two Sum - Closest Pair
# Using Two Pointer
def minAbsSumPair(arr):
# Sorting the array in ascending order
arr.sort()
i, j = 0, len(arr) - 1
# Initializing sum with the first and last elements
sum_val = arr[i] + arr[j]
# Initializing the result with the absolute value
# of the initial sum
diff = abs(sum_val)
while i < j:
# If we have zero sum, there's no result
# better. Hence, we return 0.
if arr[i] + arr[j] == 0:
return 0
# If we get a better result, we update the
# difference
if abs(arr[i] + arr[j]) < abs(diff):
diff = arr[i] + arr[j]
sum_val = arr[i] + arr[j]
elif abs(arr[i] + arr[j]) == abs(diff):
# If there are multiple pairs with the same
# minimum absolute difference, return the
# pair with the larger sum
sum_val = max(sum_val, arr[i] + arr[j])
# If the current sum is greater than zero, we
# search for a smaller sum
if arr[i] + arr[j] > 0:
j -= 1
# Else, we search for a larger sum
else:
i += 1
return sum_val
# Driver Code
arr = [0, -8, -6, 3]
print(minAbsSumPair(arr))
// C# Code for Two Sum - Closest Pair
// Using Two Pointer
using System;
public class GfG {
public static int minAbsSumPair(int[] arr)
{
// Sorting the array in ascending order
Array.Sort(arr);
int i = 0, j = arr.Length - 1;
// Initializing sum with the first and last elements
int sum = arr[i] + arr[j];
// Initializing the result with the absolute value
// of the initial sum
int diff = Math.Abs(sum);
while (i < j) {
// If we have zero sum, there's no result
// better. Hence, we return 0.
if (arr[i] + arr[j] == 0)
return 0;
// If we get a better result, we update the
// difference
if (Math.Abs(arr[i] + arr[j])
< Math.Abs(diff)) {
diff = arr[i] + arr[j];
sum = arr[i] + arr[j];
}
else if (Math.Abs(arr[i] + arr[j])
== Math.Abs(diff)) {
// If there are multiple pairs with the same
// minimum absolute difference, return the
// pair with the larger sum
sum = Math.Max(sum, arr[i] + arr[j]);
}
// If the current sum is greater than zero, we
// search for a smaller sum
if (arr[i] + arr[j] > 0)
j--;
// Else, we search for a larger sum
else
i++;
}
return sum;
}
// Driver Code
public static void Main(string[] args)
{
int[] arr = { 0, -8, -6, 3 };
Console.WriteLine(minAbsSumPair(arr));
}
}
// Javascript Code for Two Sum - Closest Pair
// Using Two Pointer
function minAbsSumPair(arr) {
// Sorting the array in ascending order
arr.sort((a, b) => a - b);
let i = 0, j = arr.length - 1;
// Initializing sum with the first and last elements
let sum = arr[i] + arr[j];
// Initializing the result with the absolute value
// of the initial sum
let diff = Math.abs(sum);
while (i < j) {
// If we have zero sum, there's no result
// better. Hence, we return 0.
if (arr[i] + arr[j] === 0)
return 0;
// If we get a better result, we update the
// difference
if (Math.abs(arr[i] + arr[j]) < Math.abs(diff)) {
diff = arr[i] + arr[j];
sum = arr[i] + arr[j];
} else if (Math.abs(arr[i] + arr[j]) === Math.abs(diff)) {
// If there are multiple pairs with the same
// minimum absolute difference, return the
// pair with the larger sum
sum = Math.max(sum, arr[i] + arr[j]);
}
// If the current sum is greater than zero, we
// search for a smaller sum
if (arr[i] + arr[j] > 0)
j--;
// Else, we search for a larger sum
else
i++;
}
return sum;
}
// Example usage
let arr = [0, -8, -6, 3];
let result = minAbsSumPair(arr);
console.log(result);
Output
3