💡 Sorting the array allows us to use two pointers to efficiently find pairs that complement the first chosen element, reducing complexity from cubic to quadratic.
Intuition
Fix one element and use two pointers to find the other two elements whose sum is closest to the target minus the fixed element.
Algorithm
- Sort the input array.
- Initialize a variable to store the closest sum.
- Iterate over the array, fixing one element at a time.
- For each fixed element, use two pointers (start and end) to find the best pair.
- Move pointers based on comparison of current sum with target to get closer.
- Update closest sum whenever a closer sum is found.
💡 Sorting enables the two-pointer technique, which is a common pattern to reduce search space in sorted arrays.
def threeSumClosest(nums, target):
nums.sort()
n = len(nums)
closest_sum = nums[0] + nums[1] + nums[2]
for i in range(n - 2):
left, right = i + 1, n - 1
while left < right:
current_sum = nums[i] + nums[left] + nums[right]
if abs(current_sum - target) < abs(closest_sum - target):
closest_sum = current_sum
if current_sum < target:
left += 1
elif current_sum > target:
right -= 1
else:
return current_sum
return closest_sum
# Driver code
if __name__ == '__main__':
print(threeSumClosest([-1, 2, 1, -4], 1)) # Output: 2
Line Notes
nums.sort()Sorting the array to apply two-pointer technique
closest_sum = nums[0] + nums[1] + nums[2]Initialize closest sum with first three elements
for i in range(n - 2)Fix one element at a time
left, right = i + 1, n - 1Initialize two pointers for the remaining elements
while left < rightLoop until pointers meet
current_sum = nums[i] + nums[left] + nums[right]Calculate current triplet sum
if abs(current_sum - target) < abs(closest_sum - target)Update closest sum if current is closer
if current_sum < target: left += 1Move left pointer right to increase sum
elif current_sum > target: right -= 1Move right pointer left to decrease sum
else: return current_sumExact match found, return immediately
import java.util.*;
public class ThreeSumClosest {
public static int threeSumClosest(int[] nums, int target) {
Arrays.sort(nums);
int n = nums.length;
int closestSum = nums[0] + nums[1] + nums[2];
for (int i = 0; i < n - 2; i++) {
int left = i + 1, right = n - 1;
while (left < right) {
int currentSum = nums[i] + nums[left] + nums[right];
if (Math.abs(currentSum - target) < Math.abs(closestSum - target)) {
closestSum = currentSum;
}
if (currentSum < target) {
left++;
} else if (currentSum > target) {
right--;
} else {
return currentSum;
}
}
}
return closestSum;
}
public static void main(String[] args) {
int[] nums = {-1, 2, 1, -4};
int target = 1;
System.out.println(threeSumClosest(nums, target)); // Output: 2
}
}
Line Notes
Arrays.sort(nums);Sort the array to enable two-pointer approach
int closestSum = nums[0] + nums[1] + nums[2];Initialize closest sum with first three elements
for (int i = 0; i < n - 2; i++)Fix one element at a time
int left = i + 1, right = n - 1;Initialize two pointers for the remaining elements
while (left < right)Loop until pointers meet
int currentSum = nums[i] + nums[left] + nums[right];Calculate current triplet sum
if (Math.abs(currentSum - target) < Math.abs(closestSum - target))Update closest sum if current is closer
if (currentSum < target) { left++; }Move left pointer right to increase sum
else if (currentSum > target) { right--; }Move right pointer left to decrease sum
else { return currentSum; }Exact match found, return immediately
#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
int n = nums.size();
int closestSum = nums[0] + nums[1] + nums[2];
for (int i = 0; i < n - 2; i++) {
int left = i + 1, right = n - 1;
while (left < right) {
int currentSum = nums[i] + nums[left] + nums[right];
if (abs(currentSum - target) < abs(closestSum - target)) {
closestSum = currentSum;
}
if (currentSum < target) {
left++;
} else if (currentSum > target) {
right--;
} else {
return currentSum;
}
}
}
return closestSum;
}
int main() {
vector<int> nums = {-1, 2, 1, -4};
int target = 1;
cout << threeSumClosest(nums, target) << endl; // Output: 2
return 0;
}
Line Notes
sort(nums.begin(), nums.end());Sort the vector to apply two-pointer technique
int closestSum = nums[0] + nums[1] + nums[2];Initialize closest sum with first three elements
for (int i = 0; i < n - 2; i++)Fix one element at a time
int left = i + 1, right = n - 1;Initialize two pointers for the remaining elements
while (left < right)Loop until pointers meet
int currentSum = nums[i] + nums[left] + nums[right];Calculate current triplet sum
if (abs(currentSum - target) < abs(closestSum - target))Update closest sum if current is closer
if (currentSum < target) { left++; }Move left pointer right to increase sum
else if (currentSum > target) { right--; }Move right pointer left to decrease sum
else { return currentSum; }Exact match found, return immediately
function threeSumClosest(nums, target) {
nums.sort((a, b) => a - b);
const n = nums.length;
let closestSum = nums[0] + nums[1] + nums[2];
for (let i = 0; i < n - 2; i++) {
let left = i + 1, right = n - 1;
while (left < right) {
const currentSum = nums[i] + nums[left] + nums[right];
if (Math.abs(currentSum - target) < Math.abs(closestSum - target)) {
closestSum = currentSum;
}
if (currentSum < target) {
left++;
} else if (currentSum > target) {
right--;
} else {
return currentSum;
}
}
}
return closestSum;
}
// Test
console.log(threeSumClosest([-1, 2, 1, -4], 1)); // Output: 2
Line Notes
nums.sort((a, b) => a - b);Sort array to enable two-pointer approach
let closestSum = nums[0] + nums[1] + nums[2];Initialize closest sum with first three elements
for (let i = 0; i < n - 2; i++)Fix one element at a time
let left = i + 1, right = n - 1;Initialize two pointers for remaining elements
while (left < right)Loop until pointers meet
const currentSum = nums[i] + nums[left] + nums[right];Calculate current triplet sum
if (Math.abs(currentSum - target) < Math.abs(closestSum - target))Update closest sum if current is closer
if (currentSum < target) { left++; }Move left pointer right to increase sum
else if (currentSum > target) { right--; }Move right pointer left to decrease sum
else { return currentSum; }Exact match found, return immediately
Sorting takes O(n log n), and the two-pointer search for each fixed element takes O(n), resulting in O(n^2) overall. Space is constant aside from input.
💡 For n=1000, this means about 1 million operations, which is efficient enough for interviews and real use.
Interview Verdict: Accepted
This approach is efficient and accepted for large inputs, making it the standard solution to implement.