思路
本来是用哈希表写的,但是去重三元组不会写,后来看了题解,使用双指针加逻辑去重,思路如下:
首先,对整个数组进行排序,方便后续去重
然后,遍历每一个元素i, 让left=i+1,right=nums.length-1,然后,left和right即为剩下的两个元素,通过让left++ right–的方式寻找符合题意的三元组。
去重逻辑如下:对于i,nums[i]=nums[i-1] continue;
对于left,nums[left]=nums[left+1],left++;
对于right,nums[right]=nums[right-1],right–;
题目描述
给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
代码
package Hash;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
public class _15三数之和_双指针 {
public static List<List<Integer>> threeSum(int[] nums) {
//首先 先对数组排序,找出所有符合的三元组,然后进行去重
List<List<Integer>> listans=new ArrayList<List<Integer>>();
Arrays.sort(nums);//数组从小到大排序
/* for(int i=0;i<nums.length;i++) {
System.out.print(nums[i]+" ");
}System.out.println();*/
for(int i=0;i<nums.length;i++) {
if(i>0&&nums[i]==nums[i-1])
continue;
int left=i+1;
int right=nums.length-1;
while(left<right) {
if(nums[i]+nums[left]+nums[right]==0) {
List<Integer> list1=new ArrayList<Integer>();
list1.add(nums[i]);
list1.add(nums[left]);
list1.add(nums[right]);
listans.add(list1);
while(right>left&&nums[right]==nums[right-1]) {
right--;
}
while(right>left&&nums[left]==nums[left+1])
left++;
right--;
left++;
}
else if(nums[i]+nums[left]+nums[right]>0) {
right--;
}else if(nums[i]+nums[left]+nums[right]<0) {
left++;
}
}
}
return listans;
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()) {
int n=sc.nextInt();
int a[]=new int[n];
for(int i=0;i<n;i++) {
a[i]=sc.nextInt();
}
System.out.println("aa");
List<List<Integer>> listans= threeSum(a);
for( List<Integer> list1:listans) {
for(Integer list2:list1) {
System.out.print(list2+" ");
}System.out.println();
}
}
}
}
总结
这个题想了很久还是没思路,特别是去重那一块,说实话,后两个left和right的去重还能理解,但是第一个i的去重,完全想不到,只能记住有这样的思路,以后遇到类似的一定要会做!!!