题目概述:
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
算法思路:
题目要求不能有重复的三元组,那么我们需要对重复的元素进行去重;可以对元素及您修改比较如果当前元素和下一个元素相同,那么我们就可以直接跳到下一个元素,而跳过当前元素;
这里我们先将数组nums进行排序(从小到大),然后依次遍历数组中的每个元素,同时定义双指针L和R,让L指向当前遍历元素的下一个,R从数组最后索引处开始;然后对nums[i]+nums[L]+nums[R]进行判断,如果三数之和等于0,那么就将他们存入到结果当中;同时还需要判断L和R的下一次指向处是否重复元素,如果重复直接跳到下一个;如果三数之和大于0,说明R指向的元素太大,那么使R–;如果之和小于0,说明L指向的元素太小,L++;
算法实现:(Java版)
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
//定义一个集合用来存储元素
List<List<Integer>> list = new ArrayList<>();
//将数组进行排序
Arrays.sort(nums);
//特殊情况讨论
if(nums==null||nums.length<3){
return list;
}
//然后对数组进行遍历
for(int i=0;i<nums.length;i++){
//因为是按照升序进行排序,因此当前元素如果大于0,那么就没有结果
if(nums[i]>0){
return list;
}
//去除重复元素
if(i>0&&nums[i] == nums[i-1]){
//跳过当前循环
continue;
}
//定义两个指针
int l = i+1;
int r = nums.length-1;
//进行双指针的移动
while(l<r){
//定义一个集合用来存储满足条件的元素
List<Integer> lst = new ArrayList<>();
int res = nums[i]+nums[l]+nums[r];
if(res==0){
//找到满足的条件
lst.add(nums[i]);
lst.add(nums[l]);
lst.add(nums[r]);
list.add(lst);
//有可能下一次l和r这两个指针移动后还会有重复的元素
while(l<r&&nums[l]==nums[l+1]){
l++;
}
while(l<r&&nums[r]==nums[r-1]){
r--;
}
//进行更新(因为这个是和l+1,r-1进行判断所有++和--指针移动到下一个想等)
l++;
r--;
}else if(res>0){
//表示数太大,那么移动r指针
r--;
}else{
//数太小移动l指针
l++;
}
}
}
return list;
}
}