题目:
给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。
示例:
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
提示:
3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4
解答:
参考15题的解法,代码如下:
int threeSumClosest(vector<int>& nums, int target) { if (nums.size() == 3) return nums.at(0) + nums.at(1) + nums.at(2); //排序 sort(nums.begin(), nums.begin() + nums.size()); long closestNum = INT_MAX; //这两个类型要大于int,因为下面存在减法,可能溢出 long sum = 0; int idx1 = 0, idx2 = 0; for (int i = 0; i < nums.size(); i++) { if (i > 0 && nums.at(i) == nums.at(i - 1))//第一个数重复的就跳过,避免重复计算 continue; idx1 = i + 1; idx2 = nums.size() - 1; while (idx1 < idx2) { sum = nums.at(i) + nums.at(idx1) + nums.at(idx2); if (sum == target) return sum; if (abs(sum - target) < abs(closestNum - target)) closestNum = sum; if (sum < target) idx1++; else if (sum > target) idx2--; } } return closestNum; }
对上面代码进行一些修改,优化后代码如下:
int threeSumClosest2(vector<int>& nums, int target) { if (nums.size() == 3) return nums.at(0) + nums.at(1) + nums.at(2); //排序 sort(nums.begin(), nums.begin() + nums.size()); //输入元素都相等,则直接返回前三个; if (nums.at(0) == nums.at(nums.size()-1)) return nums.at(0) + nums.at(1) + nums.at(2); //排除排除一些特殊情况,减少计算 if ((nums.at(0) + nums.at(1) + nums.at(2)) > target) return nums.at(0) + nums.at(1) + nums.at(2); if ((nums.at(nums.size() - 1) + nums.at(nums.size() - 2) + nums.at(nums.size() - 3)) < target) return (nums.at(nums.size() - 1) + nums.at(nums.size() - 2) + nums.at(nums.size() - 3)); long closestNum = INT_MAX; //这两个类型要大于int,因为下面存在减法,可能溢出 long sum = 0; int idx1 = 0, idx2 = 0; for (int i = 0; i < nums.size(); i++) { if (i > 0 && nums.at(i) == nums.at(i - 1))//第一个数重复的就跳过,避免重复计算 continue; idx1 = i + 1; idx2 = nums.size() - 1; while (idx1 < idx2) { //这里第二个重复的不能跳过,输入的可能都是相等的值 //if (idx1 > i+1 && nums.at(idx1) == nums.at(idx1 - 1))//第二个数重复的就跳过,避免重复计算 // continue; sum = nums.at(i) + nums.at(idx1) + nums.at(idx2); if (sum == target) return sum; if (abs(sum - target) < abs(closestNum - target)) closestNum = sum; if (sum < target) idx1++; else if (sum > target) idx2--; } } return closestNum; }