一、原题
Given an array nums
of n integers, are there elements a, b, c in nums
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.
Example:
Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
二、思路
1.3sum 问题可以转化为多个2sum问题,即 a+b = -c,-c称为目标数。先对数组排序。设置两个指针,分别指向数组的头尾,取这两个指针指向的数字的和,如果和比目标数字小,则将头指针向右移动,反之尾指针向左移动。原理:目标数/2如果落在头和尾的中间,则头和尾的和可能等于目标数,头减小和尾增加(同时)也可能等于目标数,例子:目标为 9,2+8=10,tail向左移动,得到2+7=9.
tips:
本题要求去重:1)所以目标数如果等于前一个数则略过。头尾指针移动时亦然;2)头指针从目标数index+1的位置开始,因为目标数之前的数字已经全部遍历过,再次遍历将会重复;3)头尾指针不能指向目标数
三、代码
package leetcode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ThreeSum {
public List<List<Integer>> threeSum(int[] nums) {
if(nums == null || nums.length<3)
return new ArrayList();
List<List<Integer>> result = new ArrayList<List<Integer>>();
Arrays.sort(nums);
List<Integer> taple ;
int lastkey= nums[0];int tmph,tmpt;
for(int i =0;i<nums.length;i++){
if(i!=0 && nums[i]==lastkey){
continue;
}
int target= 0-nums[i];
int head = i+1,tail= i==nums.length-1?nums.length-2:nums.length-1;
while(head<tail ){
if(tail == i){
tail--;
continue;
}
if(nums[head]+nums[tail]==target){
taple = new ArrayList<Integer>();
taple.add(nums[i]);
taple.add(nums[head]);
taple.add(nums[tail]);
result.add(taple);
tmph = nums[head];
while(head<=nums.length-1 && tmph == nums[head] ) //去重用
head++;
tmpt = nums[tail];
while(tail>=0 && tmpt == nums[tail] )//去重用
tail--;
}else if(nums[head]+nums[tail]<target){
head++;
}else{
tail--;
}
}
lastkey = nums[i];
}
return result;
}
}