LeetCode #16 Medium

3Sum Closest

Given an integer array and a target, return the sum of the three integers whose total is closest to that target.

arraytwo-pointerssorting
Open on LeetCode ↗
02

Intuition

💡

The bug that costs people this problem is comparing raw differences instead of absolute ones. You write if sum - target < best_gap because it reads naturally, and now you only ever improve from one side: every sum that overshoots the target produces a positive difference that loses to any undershoot, and every undershoot produces a negative difference that beats everything forever, including sums that are far worse. On [-1, 2, 1, -4] with target 1, the true answer 2 overshoots by exactly 1 while -4 undershoots by 5 — without the absolute value the wrong one wins. Track abs(sum - target) and the two sides become symmetric, which is the only thing 'closest' can mean. Once that is right, the search is 3Sum's skeleton: sort, fix an anchor, converge two pointers. The invariant is that best holds the smallest absolute distance seen so far, and since the array is sorted, a sum below the target can only be raised by lo += 1 and one above it lowered by hi -= 1, so each comparison still eliminates a whole block of triplets.

03

Approach

1

Sort so the sum is steerable

Sorting turns the two inner pointers into a directed search: with lo and hi inside a fixed anchor, moving lo right can only increase the sum and moving hi left can only decrease it. Without that monotonicity there is no way to know which pointer to move, and you are back to checking all O(n^3) triplets. Seed the running best with the first valid triplet so there is always something to compare against.

2

Compare on absolute distance

For each triplet compute sum and the distance abs(sum - target). Update the best only when this distance is strictly smaller than the recorded one, storing the sum itself rather than the distance's sign. This is the entire correctness point of the problem: an overshoot of 1 must beat an undershoot of 5, and only the absolute value expresses that.

3

Move the forced pointer, and stop on an exact hit

If the sum is below the target, lo += 1; if above, hi -= 1. If it equals the target the distance is zero, which cannot be improved, so return immediately. Anchoring over every index and sweeping the rest gives O(n^2) after the O(n log n) sort.

04

Solution & live demo

python
1class Solution:
2 def threeSumClosest(self, nums, target):
3 nums.sort()
4 n = len(nums)
5 best = nums[0] + nums[1] + nums[2]
6 for i in range(n - 2):
7 lo, hi = i + 1, n - 1
8 while lo < hi:
9 s = nums[i] + nums[lo] + nums[hi]
10 if abs(s - target) < abs(best - target):
11 best = s
12 if s == target:
13 return s
14 if s < target:
15 lo += 1
16 else:
17 hi -= 1
18 return best
05

Edge cases

Exactly three elements

There is one triplet, the loop measures it once, and it is returned regardless of how far from the target it lands.

An exact match exists

The distance is 0, which no other triplet can beat, so the function returns straight away instead of finishing the sweep.

All values identical, e.g. [0,0,0]

Every triplet has the same sum, so the seeded best is never improved and is returned unchanged.

Ties at equal distance on opposite sides

The strict < comparison keeps whichever was found first. The problem guarantees a unique answer, so this never changes the result, but using < rather than <= avoids pointless reassignment.

06

Complexity

Time
O(n²)
Space
O(1)
The O(n log n) sort is dominated by the anchor loop; sorting in place means no extra space beyond the sort's own.