0016. Three Sum Closest#
Problem#
Given an integer array nums of length n
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.
Examples#
Example 1:
Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
Example 2:
Input: nums = [0,0,0], target = 1
Output: 0
Constraints:#
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
Analysis#
This is similar to 0015. The closest value should lead the minimum of \(|a+b+c - target|\).
Solution 1: Naive The naive method can use three loops to find the minimum value, and will use \(O(n^3)\) time.
Solution 2: Sort + Two Pointer This solution is similar to 0015.
To build a pattern for search, we can first sort the array in a non-decending order. -> \(O(nlogn)\)
In the first loop, we can enumerate the array for the first number \(a=nums[i]\). -> \(O(n)\)
In the second loop, we can use the two-pointer algorithm for the rest of the array from \(i+1\) to \(n\) to enumerate \(b\) and \(c\). -> \(O(n)\)
use index \(j\) as the left pointer, and \(k\) as the right pointer. Assign \(b = nums[j]\) and \(c = nums[k]\). \(j\) starts from \(i+1\), and \(k\) starts from \(n\).
if \(a+b+c \ge target\), which means the value of \(|a+b+c-target|\) is still big and may be further reduced by moving the right pointer \(k\) one step left.
if \(a+b+c \lt target\), which means the value of \(|a+b+c-target|\) is still big and may be further reduced by moving the left pointer \(j\) one step right.
The loop should stop at
\(a+b+c-target=0\) or
\(j >= k\)
How to get \(k\) closest sum??
Solution#
# Solution 2:
def solution(nums, target):
nums.sort()
best = 10000
for i, a in enumerate(nums):
j, k = i + 1, len(nums) - 1
while j < k:
s = a + nums[j] + nums[k]
best = s if abs(s - target) < abs(best - target) else best
if s > target:
k -= 1
elif s < target:
j += 1
else:
return target
return best
# test
nums = [-1, 2, 1, -4]
target = 1
print(solution(nums, target))
nums = [0, 0, 0]
target = 1
print(solution(nums, target))
nums = [1, 1, 1, 1]
target = 100
print(solution(nums, target))
2
0
3
The above code can be improved:
skip duplicates as in 0015.