问题
https://leetcode.com/problems/3sum-closest/
解法《!60ms》
同leetcode 15 3Sum使用枚举加二分查找,复杂度为O( n2logn )
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
long long ret = std::numeric_limits<int>::max();
for (int i=0; i< nums.size(); i++)
{
if (i-1>=0 && nums[i] == nums[i-1])
continue;
for (int j = nums.size()-1; i+2 <= j; j--)
{
if (j+1< nums.size() && nums[j] == nums[j+1])
continue;
int L = i+1, R = j;
int t = target- nums[i] - nums[j];
// find R is first one that nums[R] >= t
while(L < R)
{
int m = L + (R-L)/2;
if ( t <= nums[m])
R = m;
else
L = m+1;
}
int now;
int two = nums[i] + nums[j];
if (R == j)
now = nums[R-1] + two;
else if (R== i+1)
{
now = nums[R] + two;
}else{
if (abs(t-nums[R-1]) < abs(nums[R] -t))
now = nums[R-1] +two;
else
now = nums[R] + two;
}
if (abs(ret - target) > abs(now-target))
ret = now;
}
}
return ret;
}
};
解法二(12ms)
枚举第一个数,对第二个数从前到后,第三个数从后到前,如果比target小就增大第二个数,如果大就减小第三个数。
复杂度O(
n2
)
class Solution {
public:
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end());
if (nums.size() < 3)
return 0;
int ret = nums[0] + nums[1] + nums[2];
if (nums.size() == 3) return ret;
for (int i=0; i< nums.size() -2; i++)
{
int j= i+1;
int k= nums.size() -1;
while(j < k)
{
int now = nums[i]+ nums[j]+nums[k];
if (abs(now-target)< abs(ret-target))
ret = now;
if (abs(ret-target)==0)
return ret;
if (now < target)
j++;
else
k--;
}
}
return ret;
}
};