LeetCode 三数之和 — 优化解法
LeetCode 三数之和 — 改进解法
题目:给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],
满足要求的三元组集合为:
[ [-1, 0, 1], [-1, -1, 2] ]
最开始做的解法是先将整个数组排序;然后遍历前两个数(a和b)的所有情况(n^2);对于第三个数,则从剩余的数中(即从第二个数下一个位置开始到末尾)利用二分查找出是否存在数字 -(a+b)即可。 复杂度O(n^2·logn) :
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
Map<Integer,Integer> mi = new HashMap();
for(int i=0;i<nums.length-1;i++) {
if(mi.get(nums[i]) != null) continue; //记录i下标读过的数字
mi.put(nums[i],1);
Map<Integer,Integer> mj = new HashMap();
for(int j=i+1;j<nums.length;j++) {
if(mj.get(nums[j]) != null) continue; //记录j下标读过的数字
mj.put(nums[j],1);
int temp = -(nums[i]+nums[j]);
if(bSearch(nums,j+1,nums.length-1,temp) == false) continue; //二分搜索j下标之后的区间是否有数字temp
ans.add(Arrays.asList(nums[i],nums[j],temp));
}
}
return ans;
}
//二分算法
public boolean bSearch(int[] nums,int s,int e,int key) {
int start=s,end=e,mid;
while(start<=end){
mid = (start+end)/2;
if(key < nums[mid]) end=mid-1;
else if(key > nums[mid]) start=mid+1;
else if(key == nums[mid]) return true;
}
return false;
}
}
里面有两个用了哈希的地方,所以时间复杂度应该还要乘上一个常数K...(解数组相关的题感觉总有些依赖哈希的方法=_= ...)
最近做了另一个数组区间相关的题目,受其解法的启发,打算对这道题解法进行优化。
还是先对数组进行排序;对第一个数字(a)进行遍历,而然后在剩余的数中用前后指针的方法找出两个和为-a的数字:两个指针left和right;left初始化为数字a的下一位置,right为最后一个位置。比较nums[left]+nums[right]+a和0的大小;如果大于0则right--,小于就left++。 其中在添加结果集时需考虑去重问题,用个哈希判断是否有重复就行了,复杂度O(n^2·K) :
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
Arrays.sort(nums);
Map<Integer,Integer> mi = new HashMap();
for(int i=0;i<nums.length-2;i++) {
if(mi.get(nums[i]) != null) continue; //记录i下标读过的数字
mi.put(nums[i],1);
Map<Integer,Integer> mj = new HashMap();
int l = i+1, r = nums.length-1, temp;
while(l<r) {
temp = nums[i] + nums[l] + nums[r];
if(temp < 0) {
l++;
} else if(temp > 0) {
r--;
} else {
if((mj.get(nums[l])) == null) {
ans.add(Arrays.asList(nums[i], nums[l], nums[r]));
mj.put(nums[l], 1);
}
l++; r--;
}
}
}
return ans;
}
}
LeetCode 三数之和 — 优化解法的更多相关文章
- [leetcode]三数之和
三数之和 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答案中不可以包含重复 ...
- [LeetCode] 3Sum Closest 最近三数之和
Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...
- [LeetCode] 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] 923. 3Sum With Multiplicity 三数之和的多种情况
Given an integer array A, and an integer target, return the number of tuples i, j, k such that i &l ...
- [LeetCode] 16. 3Sum Closest 最近三数之和
Given an array nums of n integers and an integer target, find three integers in nums such that the s ...
- [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:两数之和、三数之和、四数之和
LeetCode:两数之和.三数之和.四数之和 多数之和问题,利用哈希集合减少时间复杂度以及多指针收缩窗口的巧妙解法 No.1 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在 ...
- [LeetCode] 3Sum Smaller 三数之和较小值
Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 < ...
- LeetCode(15):三数之和
Medium! 题目描述: 给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组. 注意:答 ...
随机推荐
- 浅谈css的行内类型标签和块级标签
常用标签的行内类型标签有:a.span.img:块级标签有:div.p.h1~6.ul.ol.li.dl.dt.dd. 行内类型标签的特征:标签的大小由标签的内容决定,不能设置width和height ...
- 42使用NanoPiM1Plus在Android4.4.2下的录音测试
42使用NanoPiM1Plus在Android4.4.2下的录音测试 大文实验室/大文哥壹捌陆捌零陆捌捌陆捌贰21504965 AT qq.com完成时间:2017/12/5 17:51版本:V1. ...
- python 正则表达式操作
正则表达式操作 本模块提供了类似于Perl的正则表达式匹配操作.要匹配的模式和字符串可以是Unicode字符串以及8位字符串. 正则表达式使用反斜杠字符('\')来表示特殊的形式或者来允许使用特殊的 ...
- 继续C#开发or转做产品
本人今年大四,C#开发,在一家公司实习了一年后,面临一个选择,是继续C#开发还是转做产品?我C#开发能力目前还一般,但很有兴趣.也喜欢设计与创意,做过产品专员.求大婶们指导!
- 调度kettle使用taskctl我该怎么部署
转载自: http://www.taskctl.com/forum/detail_133.html 最近在QQ群看到有小伙伴在问用taskctl调度kettle,都要安装些什么呢?都支持哪些平台上的k ...
- 常用css属性总结
边框修饰:border------>top,bottom,left,right上下左右边框 分为:color,类型style{ groove,dashed,ridge,solid}一个值---- ...
- golang协程——通道channel阻塞
新的一年开始了,不管今天以前发生了什么,向前看,就够了. 说到channel,就一定要说一说线程了.任何实际项目,无论大小,并发是必然存在的.并发的存在,就涉及到线程通信.在当下的开发语言中,线程通讯 ...
- MySql学习笔记(三) —— 聚集函数的使用
1.AVG() 求平均数 select avg(prod_price) as avg_price from products; --返回商品价格的平均值 ; --返回生产商id为1003的商品价格平均 ...
- PMP 学习心得
前两天刚考完 PMP,松了一口气,终于考完了,虽然心里有点慌,不知道自己会不会过.学习 PMP 这三个月还是很充实的.不断的看视频,做题目,功夫不负有心人,也算是学到了一些东西.至少知道了一个项目的启 ...
- sql之inner join
这个嘛...经常写sql写的我怀疑自己:算了还是记下来了再强调一遍!再强调一遍!再强调一遍!:虽然很傻逼... inner join(等值连接) 只返回两个表中联结字段相等的行