题目:三数之和

内容

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]
思路
题目实现可分为两个步骤,分别是(1)寻找三个满足条件的元素(2)去重复
对于第一个小问题,首先考虑三个for循环,直接寻找
1.第一个数字(num1)选取范围1~n
2.第二个数字(num2)选取范围num1+1~n
3.第三个数字(num3)选取范围num2+1~n
代码如下:
 //寻找三数之和为0的数 C++
vector<int> vec();
unsigned int num1 = , num2 = , num3 = ;
for (num1; num1 < nums.size() - ; num1++){
for (num2 = num1 + ; num2 < nums.size() - ; num2++){
for (num3 = num2 + ; num3 < nums.size(); num3++){
if (nums[num1] + nums[num2] + nums[num3] == ){
vec[] = nums[num1];
vec[] = nums[num2];
vec[] = nums[num3];
vecs.push_back(vec);
}
}
}
}

第二个小问题去重复

C++ 的STL提供有去重算法unique,直接去重即可

1.在寻找满足条件的三个数字之前要先排序,防止相同的vec因为内部元素顺序不同去不了重复,如[1,2,3]和[2,1,3]会判定为不重复

2.对于vecs结果进行去重,去重之前一定要再次排序,因为unique函数只是比较相邻的两个元素是否重复,如果重复就将重复的放到尾部,如果不限排序,对于vecs[[1,2,3],[0,0,0],[1,2,3]],因为相邻的元素都不想等([1,2,3]≠[0,0,0]),系统会去重失败

去重代码如下:

 //先排序,方便去重
sort(nums.begin(), nums.end());
//寻找三个满足条件的数字代码省略。。。。
//去重
sort(vecs.begin(), vecs.end());
vecs.erase(unique(vecs.begin(), vecs.end()), vecs.end()); return vecs;

此外,还要考虑异常的情况,当传入的数组长度小于3时,无法给出满足条件的解,应返回空的容器

完整代码如下:

 vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> vecs;
//异常判断
if (nums.size() < )
return vecs; //先排序,方便去重
sort(nums.begin(), nums.end()); //寻找三数之和为0的数
vector<int> vec();
unsigned int num1 = , num2 = , num3 = ;
for (num1; num1 < nums.size() - ; num1++){
for (num2 = num1 + ; num2 < nums.size() - ; num2++){
for (num3 = num2 + ; num3 < nums.size(); num3++){
if (nums[num1] + nums[num2] + nums[num3] == ){
vec[] = nums[num1];
vec[] = nums[num2];
vec[] = nums[num3];
vecs.push_back(vec);
}
}
}
} //去重
sort(vecs.begin(), vecs.end());
vecs.erase(unique(vecs.begin(), vecs.end()), vecs.end()); return vecs;
}

对于较短的输入,能给出合适的结果,然后对于巨长的数组,系统提示运算时间过长,因此需要优化代码。

根据题目所给的条件,可以看出三个数字之和是定值,因此,当我们选取第一个数字num1后,问题变为寻找和为0-num1的两个数字。

可以观察到,因为数组是有序的,我们可以设置两个指针从两边同时选取

 int targetSum =  - nums[num1];
while (pLeft < pRight ){
int sum = nums[pLeft] + nums[pRight];
if (sum > targetSum || nums[pRight] == nums[pRight-]){
pRight--;
}
else if (sum < targetSum || nums[pLeft] == nums[pLeft - ]){
pLeft++;
}
else{
vec[] = nums[num1];
vec[] = nums[pLeft];
vec[] = nums[pRight];
vecs.push_back(vec);
pLeft++;
pRight--;
}
}

也因为数组是排序的,为了如果我们选取的第一个数子大于0,则后两个必然大于0,可以跳出循环

对于重复的数字,我们可以选择跳过

完整代码如下:

 vector<vector<int>> threeSum(vector<int>& nums) {
vector<vector<int>> vecs;
//异常判断
if (nums.size() < )
return vecs; //先排序,方便去重
sort(nums.begin(), nums.end()); //寻找三数之和为0的数
vector<int> vec();
unsigned int num1 = , num2 = , num3 = ;
for (num1; num1 < nums.size() - ; num1++){
if (nums[num1] * > )//数组是从小到大排序
break;
if (num1 != && nums[num1] == nums[num1 - ])
continue; int pLeft, pRight;
pLeft = num1+;
pRight = nums.size() - ; int targetSum = - nums[num1];
while (pLeft < pRight ){
int sum = nums[pLeft] + nums[pRight];
if (sum > targetSum || nums[pRight] == nums[pRight-]){
pRight--;
}
else if (sum < targetSum || nums[pLeft] == nums[pLeft - ]){
pLeft++;
}
else{
vec[] = nums[num1];
vec[] = nums[pLeft];
vec[] = nums[pRight];
vecs.push_back(vec);
pLeft++;
pRight--;
}
}
} //去重
sort(vecs.begin(), vecs.end());
vecs.erase(unique(vecs.begin(), vecs.end()), vecs.end()); return vecs;
}

对于复杂测试案例的运行时间是60ms,通过题目!

												

LeeCode数组第15题三数之和的更多相关文章

  1. LeetCode 第15题-三数之和

    1. 题目 2.题目分析与思路 3.思路 1. 题目 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且 ...

  2. leetcode 刷题(数组篇)15题 三数之和 (双指针)

    很有意思的一道题,值得好好思考,虽然难度只有Mid,但是个人觉得不比Hard简单 题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b ...

  3. [LeetCode] 15. 3Sum 三数之和

    Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all un ...

  4. 【LeetCode】15、三数之和为0

    题目等级:3Sum(Medium) 题目描述: Given an array nums of n integers, are there elements a, b, c in nums such t ...

  5. 【LeetCode】15. 3Sum 三数之和

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

  6. [leetcode]15. 3Sum三数之和

    Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find ...

  7. Leetcode(15)-三数之和

    给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...

  8. 【LeetCode 15】三数之和

    题目链接 [题解] 先把n个数字升序排个序. 然后枚举三元组最左边的那个数字是第i个数字. 之后用两个指针l,r移动来获取三元组的第2个和第3个数字. (初始值,l=i+1,r = n-1); 如果a ...

  9. [LeetCode] 259. 3Sum Smaller 三数之和较小值

    Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 < ...

随机推荐

  1. 【Unity Shaders】Using Textures for Effects——通过修改UV坐标来滚动textures

    本系列主要参考<Unity Shaders and Effects Cookbook>一书(感谢原书作者),同时会加上一点个人理解或拓展. 这里是本书所有的插图.这里是本书所需的代码和资源 ...

  2. [转].NET程序破解仅需三步

    近期开发公司商城,为了简化开发用了V5Shop网店程序.本来预计一个月完工,哪知道出现一堆问题大大增加了我的工作量(早知道还不如全部自己写了). 破V5Shop真不地道,说是免费的,结果程序一大堆问题 ...

  3. Java进阶(二十二)使用FileOutputStream写入文件

    Java使用FileOutputStream写入文件 绪 在Java中,文件输出流是一种用于处理原始二进制数据的字节流类.为了将数据写入到文件中,必须将数据转换为字节,并保存到文件.请参阅下面的完整的 ...

  4. OAF实现下拉菜单联动

    当需要输入多个下拉菜单选项时,可能某些下拉菜单是有级联关系的.这时候就需要使用级联的下拉菜单来解决.下面的教程将介绍如何使用ppr制作级联下拉菜单 一.新建AM 在test.oracle.apps.c ...

  5. C++之标准输入输出

    由于在公司,无法上传图片,往后补上. 关于C++的标准输入输出,其实就相当于C语言的scanf和printf,只不过C++用cin和cout这样称为流的机制. #include <iostrea ...

  6. LAV Filter 源代码分析 3: LAV Video (1)

    LAV Video 是使用很广泛的DirectShow Filter.它封装了FFMPEG中的libavcodec,支持十分广泛的视频格式的解码.在这里对其源代码进行详细的分析. LAV Video ...

  7. PS 图像特效算法— —渐变

    这个特效利用图层的混合原理,先设置一个遮罩层,然后用遮罩层与原图进行相乘,遮罩层不同,图像最后呈现的渐变效果也不一样. clc;clear all;close all;addpath('E:\Phot ...

  8. C语言算法---求鞍点

    题目:有一个3X4矩阵,要求输出其鞍点(行列均最大的值),以及它的行号和列号. int a[3][4] = {{123,94,-10,218},                          {3 ...

  9. LeetCode(51)- Count and Say

    题目: The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, 1211, 11 ...

  10. Java Socket:Java-NIO-ServerSocketChannel

    ServerSocketChannel 让我们从最简单的ServerSocketChannel来开始对socket通道类的讨论 ServerSocketChannel是一个基于通道的socket监听器 ...