3Sum Closest
LeetCode #16 · Medium · Arrays · C++ solution with worked-out approach and complexity analysis.
Approach
Sorting + Two Pointers
Key insight
Similar to the 3Sum problem, sorting the array allows us to use two pointers to efficiently find triplets. Since we are looking for the closest sum, we iterate through the array and for each element, we try to find two other elements such that their sum approaches the target.
Strategy
- 1Sort the array in ascending order.
- 2Iterate through the array with index i from 0 to n-1.
- 3For each i, use two pointers, left = i + 1 and right = n - 1.
- 4Calculate current sum = nums[i] + nums[left] + nums[right].
- 5If abs(target - sum) < abs(target - result), update result.
- 6If sum < target, increment left (need larger sum).
- 7If sum > target, decrement right (need smaller sum).
- 8If sum == target, return sum immediately (distance is 0).
Time
O(N^2)
One loop for i and nested while loop for pointers.
Space
O(log N) or O(N)
on sort implementation space.
Problem description(from LeetCode)
Given an integer array nums of length n and an integer target, find three integers at distinct indices 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.
Examples
Example 1
- Input:
- nums = [-1,2,1,-4], target = 1
- Output:
- 2
- Note:
- The sum that is closest to the target is 2 (-1 + 2 + 1 = 2). Input: nums = [0,0,0], target = 1 Output: 0 Explanation: The sum that is closest to the target is 0 (0 + 0 + 0 = 0).
Constraints
- •3 <= nums.length <= 500
- •-1000 <= nums[i] <= 1000
- •-10^4 <= target <= 10^4
C++ Solution
solution.cpp
class Solution {
public:
int threeSumClosest(vector<int> &nums, int target) {
// Initialize result with the sum of the first three elements
int result = nums[0] + nums[1] + nums[2];
sort(nums.begin(), nums.end());
for (int i = 0, n = nums.size(); i < n - 2; i++) {
int left = i + 1, right = n - 1;
while (left < right) {
int sum = nums[i] + nums[left] + nums[right];
if (abs(target - sum) < abs(target - result)) {
result = sum;
}
if (sum == target) {
return target;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
return result;
}
};