题目:

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. php 学习随笔

    ---恢复内容开始--- round进行格式化数值(进位规则遵守“四舍六入五双”,即前一位是奇数,则进一,前一位是偶数则舍入,因此,rount(1.5)=2,round(2.5)=2,round(0. ...

  2. #ifdef endif 用法

    "#ifdef 语句1 程序2 #endif“ 可翻译为:如果宏定义了语句1则程序2. 作用:我们可以用它区隔一些与特定头文件.程序库和其他文件版本有关的代码. 代码举例:新建define. ...

  3. 了不得,我可能发现了Jar 包冲突的秘密

    一.前言 这篇是类加载器相关的第三篇: 实战分析Tomcat的类加载器结构(使用Eclipse MAT验证) 还是Tomcat,关于类加载器的趣味实验 昨天下午刚写了篇 类加载器相关的,晚上想着验证个 ...

  4. 【Codeforces Round #506 (Div. 3) 】

    A:https://www.cnblogs.com/myx12345/p/9844334.html B:https://www.cnblogs.com/myx12345/p/9844368.html ...

  5. Codeforces956D. Contact ATC

    $n \leq 100000$个飞机在坐标轴上,给坐标给速度,坐标速度异号,还有一个风速在$[-w,w]$区间,$w$比最小的速度绝对值要小.由于风速不知道,所以问有多少对飞机可能在原点相遇. 思维定 ...

  6. android图片上传

    package com.example.center; import java.io.ByteArrayOutputStream;import java.io.InputStream; import ...

  7. 安装破解版的webstorne

    参考以下链接:https://www.cnblogs.com/cui-cui/p/8507435.html

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

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

  9. db2 获取自增主键的方法

    1.用SEQUENCES方式 建表语句 CREATE TABLE TEST1( PKEY INTEGER NOT NULL, NAME VARCHAR(100), SEX VARCHAR(100), ...

  10. 使用CSS去除 去掉超链接的下划线方法

    我们可以用CSS语法来控制超链接的形式.颜色变化,为什么链接一定要使用下划线和颜色区分呢? 其主要原因主要是考虑到   1.视力差的人 2.色盲的人 ... 下面我们做一个这样的链接:未被点击时超链接 ...