题目:
三数之和
给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
示例 1:
输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]
一、算法介绍
本题采用双指针算法。双指针算法需要先将给定的输入数组进行排序,这样可以避免出现重复元素。
- 解题思路:
假设输入数组为n,数组长度为len;
1)固定 3个指针中最左(最小)数字的指针 i,双指针 right,left 分设在数组索引 [i+1,len-1] 两端,通过双指针交替向中间移动,记录对于每个固定指针 i 的所有满足 nums[i] + nums[right] + nums[left] == 0 的right,left组合。
2)如果 nums[i] + nums[right] + nums[left] =0,存储下这三个值,左右指针各向中间移一个位置。
3)如果nums[i] + nums[right] + nums[left] <0,说明 nums[right]太小,left右移。
4)如果nums[i] + nums[right] + nums[left] >0,说明 nums[right]太大,right 左移。
【简单一句话,先固定第一个数a,然后b、c只能从两边向中间靠(在a之后)。细节条件就是去重处理】
二、代码
package suanfa.三数之和_8;
import java.util.*;
public class Eight {
public static void main(String[] args) {
System.out.println(Eight.solution(new int[]{-1, 0, 1, 2, -1, -4}));
}
public static List<List<Integer>> solution(int[] n){
Arrays.sort(n);
int len = n.length;
//可以去重复
Set<List<Integer>> lists = new HashSet<>();
// List<List<Integer>> lists = new ArrayList<>(); //会有重复元素
for (int i = 0; i < len; i++) {
int l = i + 1;
int r = len - 1;
while (l < r){
if(n[i] + n[l] + n[r] == 0){
lists.add(Arrays.asList(n[i],n[l],n[r]));
l++;
r--;
}else if(n[i] + n[l] + n[r] <= 0){
l++;
}else {
r--;
}
}
}
List<List<Integer>> ans = new ArrayList<>();
ans.addAll(lists);
return ans;
}
}