LeeCode数组第15题三数之和
题目:三数之和
内容:
给定一个包含 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题三数之和的更多相关文章
- LeetCode 第15题-三数之和
1. 题目 2.题目分析与思路 3.思路 1. 题目 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且 ...
- leetcode 刷题(数组篇)15题 三数之和 (双指针)
很有意思的一道题,值得好好思考,虽然难度只有Mid,但是个人觉得不比Hard简单 题目描述 给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b ...
- [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 ...
- 【LeetCode】15、三数之和为0
题目等级:3Sum(Medium) 题目描述: Given an array nums of n integers, are there elements a, b, c in nums such t ...
- 【LeetCode】15. 3Sum 三数之和
作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 个人公众号:负雪明烛 本文关键词:3sum, 三数之和,题解,leetcode, 力扣,P ...
- [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 ...
- Leetcode(15)-三数之和
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复的三元组. ...
- 【LeetCode 15】三数之和
题目链接 [题解] 先把n个数字升序排个序. 然后枚举三元组最左边的那个数字是第i个数字. 之后用两个指针l,r移动来获取三元组的第2个和第3个数字. (初始值,l=i+1,r = n-1); 如果a ...
- [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 < ...
随机推荐
- OJ题:奇偶归一猜想——求归一过程中的最大值
题目: 题目内容: 奇偶归一猜想--对于每一个正整数,如果它是奇数,则对它乘3再加1,如果它是偶数,则对它除以2,如此循环,最终都能够得到1. 如n = 11,得序列:11, 34, 17, 52, ...
- Git版本控制:Git查阅、撤销文件修改和撤销文件追踪
http://blog.csdn.net/pipisorry/article/details/47867097 查看文件的修改历史 git log --pretty=oneline 文件名 # 显示修 ...
- STL - string(典型操作demo)
1String概念 string是STL的字符串类型,通常用来表示字符串.而在使用string之前,字符串通常是用char*表示的.string与char*都可以用来表示字符串,那么二者有什么区别呢 ...
- Cocos2D物理碰撞不按预期工作的排查工作
如果该碰撞的节点不碰撞或反过来不该碰的碰撞了,你可以检查一下几个方面: 1.对应2个节点的分类和掩码必须匹配.如果它们应该碰撞则一个节点的分类应该在另一个节点的掩码中,反之亦然. 2.注意空的分类和掩 ...
- 安卓Tv开发(二)移动智能电视之焦点控制(按键事件)
原文:http://blog.csdn.net/sk719887916/article/details/44781475 skay 前言:移动智能设备的发展,推动了安卓另一个领域,包括智能电视和智能家 ...
- 总账追朔各模块SQL
SELECT gjh.set_of_books_id, gjl.je_line_num, mta.organization_id, ood.organization_code, ood.organiz ...
- OpenGL Shader Key Points (1)
1. Shader起步 1.1. 可编程管线 仅考虑Vertex shader和fragment shader: 1.2. Shader Object 在编译阶段生成,把shader源代码编译成 ...
- 网站开发进阶(八)tomcat异常日志分析及处理
tomcat异常日志分析及处理 日志信息如下: 2015-10-29 18:39:49 org.apache.coyote.http11.Http11Protocol pause 信息: Pausin ...
- Android群英传笔记——第二章:Android开发工具新接触
Android群英传笔记--第二章:Android开发工具新接触 其实这一章并没什么可讲的,前面的安装Android studio的我们可以直接跳过,如果有兴趣的,可以去看看Google主推-Andr ...
- android4.2添加重启菜单项
本文主要是针对android4.2关机菜单添加重启功能 A.关机提示 android4.2/frameworks/base/policy/src/com/android/internal/policy ...