难点在于跳过重复,多举例子就好了,当然也可以使用set去重复但是效率较低。
直接暴力会超时,时间复杂度为O(n2lgn).
解法一:两层循环,第三个使用二分查找。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res=new ArrayList<List<Integer>>();
for(int i=0;i<nums.length-2;i++){
if(i>0 && nums[i-1]==nums[i])
continue;
for(int j=nums.length-1;j>i+1;j--){
if(j<nums.length-1 && nums[j+1]==nums[j])
continue;
int first=i+1,end=j-1;
int mid=(i+j)/2;
int temp=-(nums[i]+nums[j]);
while(first<=end){
if(nums[mid]>temp)
end=mid-1;
else if(nums[mid]<temp)
first=mid+1;
else{
List<Integer> tempres=new ArrayList<Integer>();
tempres.add(nums[i]);
tempres.add(nums[mid]);
tempres.add(nums[j]);
res.add(new ArrayList(tempres));
break;
}
mid=(first+end)/2;
}
}
}
return res;
}
}
解法二: 一层循环,然后转换成求两个数和的问题。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res=new ArrayList<List<Integer>>();
for(int i=0;i<nums.length-2;i++){
if(i>0 && nums[i-1]==nums[i])
continue;
int temp=-nums[i];
Map<Integer,Integer> map=new HashMap<Integer, Integer>();
int tempnum=-1;
for(int j=i+1;j<nums.length;j++){
int temp2=temp-nums[j];
if(map.containsKey(temp2) && nums[j]!=tempnum){
List<Integer> tempres=new ArrayList<Integer>();
tempres.add(nums[i]);
tempres.add(temp2);
tempres.add(nums[j]);
res.add(new ArrayList(tempres));
tempnum=nums[j];
}
map.put(nums[j],j);
}
}
return res;
}
}
解法三:一层循环,双指针。
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
Arrays.sort(nums);
List<List<Integer>> res=new ArrayList<List<Integer>>();
for(int i=0;i<nums.length-2;i++){
if(i>0 && nums[i-1]==nums[i])
continue;
int first=i+1,end=nums.length-1;
int temp=-nums[i];
while(first<end){
while(nums[first]+nums[end]<temp && first<end)
first++;
while(nums[first]+nums[end]>temp && first<end)
end--;
if(first<end && nums[first]+nums[end]==temp){
List<Integer> tempres=new ArrayList<Integer>();
tempres.add(nums[i]);
tempres.add(nums[first]);
tempres.add(nums[end]);
res.add(new ArrayList(tempres));
while(first<end) {
if(nums[first+1]==nums[first])
first++;
else
break;
}
first++;
while(first<=end){
if(nums[end-1]==nums[end])
end--;
else
break;
}
end--;
}
}
}
return res;
}
}