给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
例如,给定数组 nums = [-1,2,1,-4], 和 target = 1.
与 target 最接近的三个数的和为 2. (-1 + 2 + 1 = 2).
暴力法
#include<iostream>
#include<vector>
using namespace std;
int threeSumClosest(vector<int>& nums, int target) {
int len = nums.size();
int tmp = 0;
int res;
int minDiff = 0;
int diff = abs(nums[0] + nums[1] + nums[2] - target);
for (int i = 0; i < len - 2; i++) {
for (int j = i + 1; j < len - 1; j++) {
for (int k = j + 1; k < len; k++) {
tmp = nums[i] + nums[j] + nums[k];
if (abs(target - tmp) <= diff) {
diff = abs(target - tmp); // don't forget
res = tmp;
}
}
}
}
return res;
}
int main(){
vector<int> nums = {1,1, -1, -1, 3};
int target = -1;
int res = threeSumClosest(nums, target);
cout << res << endl;
}
排序+双指针法
思路
现将该数组进行排序操作,在下面的代码中,使用的为升序(若设置为降序原理类似),先设置一个起点nums[i]
,start
为nums[i]
的下一个元素,end
则为数组的最后一个元素;若三数字的和sum大于target
,也就将end前移一个元素,小于target则start后移一个元素,target和sum相同,直接返回。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int threeSumClosest(vector<int>& nums, int target) {
sort(nums.begin(), nums.end()); // 升序
int start, end;
int tmp = nums[0] + nums[1] + nums[2];
for (int i = 0; i < nums.size(); i++) {
start = i + 1;
end = nums.size() - 1;
while(start < end) {
int sum = nums[i] + nums[start] + nums[end];
if (abs(sum - target) < abs(tmp - target)) {
tmp = sum;
}
if (sum > target) {
end--;
} else if (sum < target) {
start++;
} else if (sum == target) {
return sum;
} else {
cout << "ERROR" << endl;
}
}
}
return tmp;
}
int main() {
vector<int> nums = {-1,2,1,-4};
int target = 1;
int res = threeSumClosest(nums, target);
cout << res << endl;
}