3sum(从数组中找出三个数的和为0)
2024-10-15 11:20:43
Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
Note: The solution set must not contain duplicate triplets.
For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
从上面可以看出,这样的结果可能出现多个。而且还有重复数字出现。。
我们知道求两个数的和,可以先排序,然后两端向中间找,如果求下标,则用hashmap。
这里不是求下标,所以不需要使用hashmap。
思路就是:先排序,然后遍历数组,当前元素nums[i],,并从剩下的数组中找两个数的和0-nums[i],这个做法就是两边向中间找。需要注意,排序过后会有重复元素,在外层遍历的时候,我们要跳过重复元素(当前元素 和前一个相同)。在内部遍历查找两个数的和时,也要跳过重复元素(如果当前符合要求的值刚好是重复的,就跳过那些重复的,只要计算一遍就行)。具体的跳过重复的步骤见代码。。
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> result=new ArrayList<List<Integer>>();
if(nums==null||nums.length<3) return result;
Arrays.sort(nums);
List<Integer> list;
for(int i=0;i<nums.length-2;i++){
//跳过重复的,这个跟前一个不一样就进行
if(i==0||(i>0&&nums[i]!=nums[i-1])){
//开始从剩下的数组中查找和为0-nums[i]的两个数,而且是要遍历完剩下所有元素,因为可能存在多组
int left=i+1,right=nums.length-1,sum=0-nums[i];
while(left<right){
if(nums[left]+nums[right]==sum){
//找到一组了,加到集合中
list=new ArrayList<>();
list.add(nums[i]);list.add(nums[left]);list.add(nums[right]);
result.add(list);
//跳过重复元素。这里跳到了重复节点的最后一个,也就是说还需要在++
while(left<right&&nums[left+1]==nums[left]) left++;
while(left<right&&nums[right]==nums[right-1]) right--;
left++;right--;
}else if(nums[left]+nums[right]<sum){
left++;
}else right--;
} } }
return result; }
最新文章
- redis键命令
- Domino----The Address Book does not contain a cross certificate capable of validating the public key.
- 你真的会玩SQL吗?删除重复数据且只保留一条
- css常用效果总结
- Revit自定义快递访问工具栏
- shell调用sqlplus批量执行sql文件
- 写一个基于NSURLSession的网络下载库
- 完整的多项匹配tomcat access日志的正则
- 各种浏览器的agent信息(IE Chrome Safari Firefox)
- Ubuntu 划词翻译
- Centos7.5 安装VirtualBox增强工具
- 树莓派 nfs server安装
- ng-repeat 的重复问题
- GBDT
- URL List by Category
- Requests中出现大量ASYNC_NETWORK_IO等待
- android studio 3.0之后版本自定义文件名生成apk文件
- VMWare ESX/ESXi 虚拟机硬盘的厚置备(Thick Provision)与精简置备(Thin Provision)的转换
- Laravel Debugbar
- 捡了一个非常淫荡的PHP后门,给跪了