3Sum Closest (opens in a new tab) Medium
Problem
Given an integer array nums and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.
Example
Input: nums = [-1,2,1,-4], target = 1
Output: 2
Summary
To solve this problem, we can sort the input array, iterate over each element, and use two pointers (one at the beginning and the other at the end of the array) to find pairs of elements that have the smallest difference with the target. We can then return the sum of the three integers with the smallest difference.
Solution
In TypeScript
function threeSumClosest(nums: number[], target: number): number {
nums.sort((a, b) => a - b);
let closestSum = nums[0] + nums[1] + nums[2];
const n = nums.length;
for (let i = 0; i < n - 2; i++) {
let left = i + 1;
let right = n - 1;
while (left < right) {
const currentSum = nums[i] + nums[left] + nums[right];
if (Math.abs(target - currentSum) < Math.abs(target - closestSum)) {
closestSum = currentSum;
}
if (currentSum < target) {
left++;
} else if (currentSum > target) {
right--;
} else {
return currentSum;
}
}
}
return closestSum;
}
In Python
def threeSumClosest(nums, target):
nums.sort()
closest_sum = nums[0] + nums[1] + nums[2]
n = len(nums)
for i in range(n - 2):
left = i + 1
right = n - 1
while left < right:
current_sum = nums[i] + nums[left] + nums[right]
if abs(target - current_sum) < abs(target - closest_sum):
closest_sum = current_sum
if current_sum < target:
left += 1
elif current_sum > target:
right -= 1
else:
return current_sum
return closest_sum
Step-by-step explanation
- Sort the input array nums in ascending order.
nums.sort((a, b) => a - b);
- Initialize the
closestSum
variable to the sum of the first three elements in the sorted array. This variable will store the current closest sum to the target.
let closestSum = nums[0] + nums[1] + nums[2];
- Iterate through the array using a
for
loop, leaving the last two elements out of the iteration as we need to find triplets:
for (let i = 0; i < n - 2; i++) {
// ...
}
- Inside the loop, initialize two pointers,
left
andright
. left starts right after the current element (i + 1), and right starts at the end of the array.
let left = i + 1;
let right = n - 1;
- Use a
while
loop to iterate through the remaining elements using theleft
andright
pointers, as long asleft
is less thanright
.
while (left < right) {
// ...
}
- Calculate the current sum of the three integers (nums[i], nums[left], and nums[right]):
const currentSum = nums[i] + nums[left] + nums[right];
- Compare the absolute difference between the
currentSum
and the target with the absolute difference between theclosestSum
and the target. If the absolute difference for thecurrentSum
is smaller, update theclosestSum
.
if (Math.abs(target - currentSum) < Math.abs(target - closestSum)) {
closestSum = currentSum;
}
- If the
currentSum
is less than the target, increment theleft
pointer to increase the sum:
if (currentSum < target) {
left++;
}
- If the
currentSum
is greater than the target, decrement theright
pointer to decrease the sum:
else if (currentSum > target) {
right--;
}
- If the
currentSum
is equal to the target, we have found the optimal solution, and we can return thecurrentSum
immediately:
else {
return currentSum;
}
- After the loop ends, return the
closestSum
, which stores the sum of the three integers with the smallest difference to the target:
return closestSum;
Complexity Analysis
Time Complexity
The time complexity of this solution is O(n^2), where n is the length of the input array. The sorting step takes O(n log n) time, and the nested loop takes O(n^2) time in the worst case.
Space Complexity
The space complexity of this solution is O(log n) due to the sorting step. The in-place sorting does not require additional space except for some space required by the sorting algorithm.