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] ]
解法一:使用HashSet来去重。
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
HashSet<LinkedList<Integer>> set = new HashSet<>();//使用 HashSet来去重
for(int i=0;i<nums.length-2;i++){
int left=i+1,right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum==0){
LinkedList<Integer> list = new LinkedList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
set.add(list);//若list在之前已经加入set中,则加入失败
left++;right--;
}else if(sum>0) right--;
else left++;
}
}
List<List<Integer>> list = new LinkedList<>(set);
return list;
}
解法二:使用while语句来跳过重复的元素。
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res = new LinkedList<>();
for(int i=0;i<nums.length-2;i++){
if(nums[i]>0) break;
if(i>0 && nums[i]==nums[i-1]) continue;
int left=i+1,right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[left]+nums[right];
if(sum==0){
List<Integer> list=new LinkedList<>();
list.add(nums[i]);
list.add(nums[left]);
list.add(nums[right]);
res.add(list);
while(left<right && nums[left+1]==nums[left]) left++;//跳出条件为 nums[left+1]!=nums[left],此时left还需要移动到left+1
while(left<right && nums[right-1]==nums[right]) right--;//跳出条件为nums[right-1]!=nums[right],此时right还需要移动到right-1
left++;right--;
}else if(sum > 0){
right--;
}else{
left++;
}
}
}
return res;
}
Given an array nums
of n integers and an integer target
, are there elements a, b, c, and d in nums
such that a + b + c + d = target
? Find all unique quadruplets in the array which gives the sum of target
.
Note:
The solution set must not contain duplicate quadruplets.
Example:
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0. A solution set is: [ [-1, 0, 0, 1], [-2, -1, 1, 2], [-2, 0, 0, 2] ]
解法一:使用HashSet来去重,4Sum与3Sum本质上并没有什么不同,3Sum使用了3个游标,4Sum使用了4个游标。
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
HashSet<List<Integer>> set = new HashSet<>();
for(int i=0;i<nums.length-3;i++){
for(int j=i+1;j<nums.length-2;j++){
if(j>i+1 && nums[j]==nums[j-1]) continue;
int left=j+1,right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[j]+nums[left]+nums[right];
if(sum==target){
LinkedList<Integer> list = new LinkedList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
set.add(list);
left++;right--;
}else if(sum>target) right--;
else left++;
}
}
}
List<List<Integer>> list = new LinkedList<>(set);
return list;
}
解法二:使用while语句来去重
public List<List<Integer>> fourSum(int[] nums, int target) {
Arrays.sort(nums);
List<List<Integer>> res = new LinkedList<>();
for(int i=0;i<nums.length-3;i++){
if(i>0 && nums[i]==nums[i-1]) continue;
for(int j=i+1;j<nums.length-2;j++){
if(j>i+1 && nums[j]==nums[j-1]) continue;
int left=j+1,right=nums.length-1;
while(left<right){
int sum=nums[i]+nums[j]+nums[left]+nums[right];
if(sum==target){
List<Integer> list = new LinkedList<>();
list.add(nums[i]);
list.add(nums[j]);
list.add(nums[left]);
list.add(nums[right]);
res.add(list);
while(left<right && nums[left+1]==nums[left]) left++;//退出条件为nums[left+1]!=nums[left],left还需要移动到left+1
while(left<right && nums[right-1]==nums[right]) right--;//退出条件为nums[right-1]!=nums[right],right还移动到right-1
left++;right--;
}else if(sum>target) right--;
else left++;
}
}
}
return res;
}