Given an array nums
of n integers 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:
Given array nums = [-1, 2, 1, -4], and target = 1. The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).
分析
该题是3Sum题目的延伸。我们先回顾一下3Sum的解法,3Sum是需要找到所有的总和等于0的3个数字的集合(a + b + c = 0)。解法是将在nums中找到所有总和等于-c的2个数字的集合(a+ b = -c)。
本地的目的是找到距离target最近的3个数字之和,即abs(a + b + c - target)最小的值。
首先对数组排序,使用k遍历数组,在 [k+1, nums.size())中寻找 abs(a + b - (target -c))的最小值即可。
Code
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
int distance = INT_MAX;
int res = 0;
sort(nums.begin(), nums.end());
for (int k = 0; k < nums.size() - 2; k ++)
{
int tmpTarget = target - nums[k];
int minDistance = INT_MAX;
int tmpRes = 0;
int i = k + 1;
int j = nums.size()-1;
while (i < j)
{
if (nums[i] + nums[j] == tmpTarget)
{
return target;
}
if (abs(nums[i] + nums[j] - tmpTarget) < minDistance)
{
minDistance = abs(nums[i] + nums[j] - tmpTarget);
tmpRes = nums[i] + nums[j] + nums[k];
}
if (nums[i] + nums[j] > tmpTarget)
{
j --;
continue;
}
else if (nums[i] + nums[j] < tmpTarget)
{
i ++;
continue;
}
}
if (minDistance < distance)
{
distance = minDistance;
res = tmpRes;
}
}
return res;
}
};
运行效率
Runtime: 16 ms, faster than 39.96% of C++ online submissions for 3Sum Closest.
Memory Usage: 9.4 MB, less than 46.24% of C++ online submissions for3Sum Closest.
从执行效率来看,本解法的耗时偏大,但是看了一下discussion中的最快解法,采用的方式与本解法类似,因此时间复杂度在同一个量级上。