力扣 题目16-- 最接近的三数之和
题目
题解
在上一题中采用了双指针的方法而这次也可以使用 但是左指针要指向i-1 右指针指向i+1 (先排序)
规则1 如果nums[left] + nums[right] + nums[i] > target 则说明left太大 向左移动 left = left - 1;
规则2 如果nums[left] + nums[right] + nums[i] < target 则说明right太小 向右移动 right = right + 1;
规则3 如果nums[left] + nums[right] + nums[i] = target 则说明有和target 差值为0的三个数 此时肯定是最接近 直接返回target
规则4 每次移动前比较一下目前的最小差值 如果小就将最小差值更新
规则5 返回时可以使用target+ difference(差值) 所以difference 不仅代表差多少还代表着+和- 所以在用 difference 比较时取绝对值
这样就可以写出这道题了 但是我们仔细观察后发现 我们可以再写两个规则
附加规则1:如果nums[0] + nums[right] + nums[i] > target 直接比较差值 然后跳出循环
这是因为 nums[0] + nums[right] + nums[i] 代表着能够遍历到的最小值 如果最小值是大于target 那么其他可能性也是大于target
并且因为之前排序了 所以其他可能性的与target 的差值只会越来越大 所以只取最小值比较即可 然后跳出循环
同理
附加规则2:如果nums[left] + nums[nums.size()-1] + nums[i] < target 直接比较差值 然后跳出循环
如果最大值都小于target 那么其他可能性也小于target 并且差值也会越来越大
代码

1 #include <iostream> 2 #include <vector> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 class Solution { 7 public: 8 int threeSumClosest(vector<int>& nums, int target) { 9 int difference = INT_MAX; 10 sort(nums.begin(),nums.end()); 11 for (int i = 1; i < nums.size()-1; i++) { 12 int left = i - 1; 13 int right = i + 1; 14 while (left>-1&&right< nums.size()) { 15 if (nums[0] + nums[right] + nums[i] > target) { 16 if (abs(difference) > nums[0] + nums[right] + nums[i] - target) { 17 difference = nums[0] + nums[right] + nums[i] - target; 18 } 19 break; 20 } 21 else if (nums[left] + nums[nums.size()-1] + nums[i] < target) { 22 if (abs(difference) > abs(nums[left] + nums[nums.size() - 1] + nums[i] - target)) { 23 difference = nums[left] + nums[nums.size() - 1] + nums[i]- target; 24 } 25 break; 26 } 27 else if (nums[left] + nums[right] + nums[i] == target|| nums[0] + nums[right] + nums[i] == target|| nums[left] + nums[nums.size() - 1] + nums[i] == target) { 28 return target; 29 } 30 else if (nums[left] + nums[right] + nums[i] > target) { 31 if (abs(difference) > nums[left] + nums[right] + nums[i] - target) { 32 difference = nums[left] + nums[right] + nums[i] - target; 33 } 34 left = left - 1; 35 } 36 else if (nums[left] + nums[right] + nums[i] < target) { 37 if (abs(difference) > abs(nums[left] + nums[right] + nums[i] - target)) { 38 difference = nums[left] + nums[right] + nums[i] - target; 39 } 40 right = right + 1; 41 } 42 43 } 44 } 45 return target+ difference; 46 } 47 }; 48 49 int main() { 50 Solution sol; 51 vector<int> nums = { -1,2,1,-4 }; 52 int target = 82; 53 int three=sol.threeSumClosest(nums, target); 54 cout << three << endl; 55 56 }