题目:

Given an array S of n integers, find three integers in S such that the sum is closest to a given number, target. Return the sum of the three integers. You may assume that each input would have
exactly one solution.

    For example, given array S = {-1 2 1 -4}, and target = 1.

    The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

题目大意:

  给定一个数组S和一个目标值target,在S中寻找三个数,使它们的和最接近target。返回三个数的和。

思路:

  一、暴力求解法:
    大体思路是用一个变量记录最小差值和要返回的值,然后枚举出全部可能的组合,推断最小差值是不是小于记录值。假设小于最小值则更新记录的最小值和终于结果。暴力求解法的时间复杂度是O(n^3)。可是能够通过一定的推断使得程序的循环次数减少,从而通过測试。推断例如以下:
    (1)、假设刚好获得了target。则直接返回。
    (2)、三重循环中假设碰到与上一次推断的数字同样则直接跳过(由于已经在上一次推断过)
  二、3Sums解法的改进版:
    大体思路是先排序,用一个变量dis保存距离,用tmp保存候选数。然后每次选择一个数字,先让这个数字和最大的两个数字相加,假设小于目标值说明和目标值相等的概率为零(即:差值为0的概率为0)。所以保存三个数字的和进tmp,保存差值进dis;假设大于目标值,说明还有可能使得结果和目标值相等(即:差值为0的概率不为0),所以问题就变成了3Sums中固定一个值然后求另外两个值的问题了(也看一看作是2Sums问题)仅仅只是在寻找是否能和目标值相等的路上保存下来不相等时的最小差值进dis。在这个撒u你法中也有一些边界调节能够直接得到答案:
    (1)、等于target,直接返回target
    (2)、假设最大的三个数加起来还小于目标值,则最接近的就是这三个数相加
    (3)、假设最小的三个数加起来还大于目标值,则最接近的就是这三个数相加
    (4)、假设当前处理过的数字上一次处理的数字同样,则不再处理

代码:

暴力法:
class Solution {
public:
int threeSumClosest(std::vector<int>& nums, int target) {
int result = target, dis = INT_MAX, dis_tmp, tmp;
if (nums.size() == 0) {
result = 0;
} for (int i = 0; i < nums.size(); ++i) {
if (i != 0 && nums[i] == nums[i - 1]) {
continue;
}
for (int j = i + 1; j < nums.size(); ++j) {
if (j != i + 1 && nums[j] == nums[j - 1]) {
continue;
}
for (int k = j + 1; k < nums.size(); ++k) {
if (k != j + 1 && nums[k] == nums[k - 1]) {
continue;
}
tmp = nums[i] + nums[j] + nums[k];
dis_tmp = abs(tmp - target);
if (dis_tmp < dis) {
dis = dis_tmp;
result = tmp;
if (result == target) {
return target;
}
}
}
}
} return result;
}
};

3Sums改进法:

class Solution {
public:
int threeSumClosest(std::vector<int>& nums, int target) { const int n = nums.size(); sort(nums.begin(),nums.end()); //假设最大的三个数加起来还小于目标值,则最接近的就是这三个数相加
if(nums[n-1] + nums[n-2] + nums[n-3] <= target) {
return nums[n-1] + nums[n-2] + nums[n-3];
} //假设最小的三个数加起来还大于目标值,则最接近的就是这三个数相加
if(nums[0] + nums[1] + nums[2] >= target) {
return nums[0] + nums[1] + nums[2];
} int tmp; //候选数
int dis = INT_MAX; //距离 //由于要选择三个数,所以i < n - 2
for (int i = 0; i < n-2; i++) {
//假设当前处理过的数字上一次处理过,则不再处理
if (i != 0 && nums[i] == nums[i-1]) {
continue;
} //假设当前扫描的值加上最大的三个数字之后假设还小于目标值
//说明和目标值相等的概率为零(即:差值为0的概率为0)
if (nums[i] + nums[n-1] + nums[n-2] <= target) {
tmp = nums[i] + nums[n-1] + nums[n-2];
if (tmp == target) {
return target;
}
dis = tmp - target; //差值最小等于候选值减去目标值
continue;
} //假设和最大的三个数字相加之后大于目标值,说明还有希望找到差值为0的值
//接下来就是求2Sums问题了(不同的一点是加了一个差值最小的推断)
int target2 = target - nums[i];
int j = i + 1;
int k = n - 1; while (j < k) {
const int sum2 = nums[j] + nums[k]; if (abs(sum2 - target2) < abs(dis)){
dis = sum2 - target2;
} if(sum2 > target2) {
k--;
} else if(sum2 < target2) {
j++;
}
else {
return target;
}
while (nums[j] == nums[j-1]) {
j++;
}
while(nums[k] == nums[k+1]) {
k--;
}
}
}
return target + dis;
}
};

LeetCode之16----3Sums Closest的更多相关文章

  1. [LeetCode][Python]16: 3Sum Closest

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 16: 3Sum Closesthttps://oj.leetcode.com ...

  2. 《LeetBook》leetcode题解(16):3Sum Closest [M]

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  3. 【一天一道LeetCode】#16. 3Sum Closest

    一天一道LeetCode系列 (一)题目: Given an array S of n integers, find three integers in S such that the sum is ...

  4. 【LeetCode】16. 3Sum Closest 最接近的三数之和

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:3sum, three sum, 三数之和,题解,lee ...

  5. 【LeetCode】16. 3Sum Closest

    题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given ...

  6. LeetCode:16. 3Sum Closest(Medium)

    1. 原题链接 https://leetcode.com/problems/3sum-closest/description/ 2. 题目要求 数组S = nums[n]包含n个整数,找出S中三个整数 ...

  7. Leetcode Array 16 3Sum Closest

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  8. LeetCode 16. 3Sum Closest(最接近的三数之和)

    LeetCode 16. 3Sum Closest(最接近的三数之和)

  9. [LeetCode] 16. 3Sum Closest 最近三数之和

    Given an array nums of n integers and an integer target, find three integers in nums such that the s ...

  10. LeetCode 15. 3Sum 16. 3Sum Closest 18. 4Sum

    n数求和,固定n-2个数,最后两个数在连续区间内一左一右根据当前求和与目标值比较移动,如果sum<target,移动较小数,否则,移动较大数 重复数处理: 使i为左至右第一个不重复数:while ...

随机推荐

  1. hdu6061[NTT推公式] 2017多校3

    /*hdu6061[NTT推公式] 2017多校3*/ #include <bits/stdc++.h> using namespace std; typedef long long LL ...

  2. 使用反射获取类中的属性(可用于动态返回PO类的列,当做表格的表头)

    //利用反射取类中的属性字段 try { Class clazz = Class.forName("houji.bean.model.TaskModel"); Field[] fi ...

  3. angular中ng-repeat去重

    [html] view plain copy print?在CODE上查看代码片派生到我的代码片 <div ng-app="myApp" ng-controller=&quo ...

  4. 转载 cc、gcc、g++、CC的区别概括

    gcc是C编译器:g++是C++编译器:linux下cc一般是一个符号连接,指向gcc:gcc和g++都是GUN(组织)的编译器.而CC则一般是makefile里面的一个名字,即宏定义,嘿,因为Lin ...

  5. js判断手机的横竖屏调整样式

    在移动端,我们经常遇到横竖屏的问题,所以我们改如何判断或针对横竖屏来写代码呢.首先需要在head中加入如下代码: <meta name="viewport" content= ...

  6. Codeforces 514C Watto and Mechanism(字典树)

    题目链接  Watto and Mechanism 题意  给出$n$个串(相当于字典),然后给出$m$个询问. 每个询问以字符串的形式给出,你需要改变这个字符串中的任意一个字符 (必须改变且只能改变 ...

  7. 2018 ICPC 沈阳网络预赛 Fantastic Graph (优先队列)

    [传送门]https://nanti.jisuanke.com/t/31447 [题目大意]:有一个二分图,问能不能找到它的一个子图,使得这个子图中所有点的度数在区间[L,R]之内. [题解]首先我们 ...

  8. python 获取时间 存入文件

    1读文件: file_path_name = '/home/robot/bzrobot_ws/src/bzrobot/bzrobot_comm/led_show_data/'+file_name+'. ...

  9. BUPT复试专题—二进制数(2012)

    https://www.nowcoder.com/practice/103dd589fed14457a673c613d8de3841?tpId=67&tqId=29634&tPage= ...

  10. 忘掉VNC/RDP,拿起手中的MobaXterm轻松上手远程桌面

    前言 原创文章,转载引用务必注明链接. 这期属于番外篇,随便写写.吐槽一下自己,关于"减少eMMC擦写,延长NAND寿命提升性能"的坑还没填完,都不好愉快地写点轻松的小项目灌水了. ...