3Sum
题意:给定一个数组,找出所有其中三个数的和是target的组合
解法:
O(N^2):先做个预处理,把其中某个数出现的次数大于等于3的全都去掉,也就是新array里一个数最多出现2次,除了0可以出现3次。建议key=Integer, value=arrayList<Integer>的哈希表,代表一个数出现在array的哪些index上。
对所有数对进行枚举,看target-该数对的值是否出现在hashtable中,观察对应的indexarray,要与数对的index没有交集才放到ans里面。
由于ans放的不是index,而是对应的数,要避免重复的情况,建议一个哈希表来判重。Hash采用最小的数+” ”+中间的数+” ”+最大的数为key来判重。
复杂度分析:预处理过程不影响算法时间上界,枚举过程为O(N^2),在查找hashtable时,由于每个数最多出现2次(0为3次),那么hashtable的查找过程最多出现9次,包括该数对本身,两个数各出现3次,所以查找hashtable的复杂度为O(1)。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Hashtable;
public class Solution137 {
public ArrayList<ArrayList<Integer>> threeSum(int[] num) {
Hashtable<Integer,Integer>hashnum=new Hashtable<Integer,Integer>();
int[] num2=new int[num.length];
int newN=0;
for (int i=0;i<num.length;i++){
if(!hashnum.containsKey(num[i])){
hashnum.put(num[i],1);
}else{
if (hashnum.get(num[i])==1){
hashnum.put(num[i],2);
}else{
if(num[i]!=0){
continue;
}else{
if(hashnum.get(0)==2){
hashnum.put(0,3);
}else{
continue;
}
}
}
}
num2[newN]=num[i];
newN++;
}
num=num2;
ArrayList<ArrayList<Integer>>ans=new ArrayList<ArrayList<Integer>>();
HashSet<String> hashAns=newHashSet<String>();
int n=newN;
Hashtable<Integer,ArrayList<Integer>>hash=new Hashtable<Integer,ArrayList<Integer>>();
for (int i=0;i<n;i++){
if(!hash.containsKey(num[i])){
hash.put(num[i], newArrayList<Integer>());
}
hash.get(num[i]).add(i);
}
for (int i=0;i<n;i++){
for (int j=i+1;j<n;j++){
intsum=num[i]+num[j];
if(hash.containsKey(-sum)){
ArrayList<Integer>temp=hash.get(-sum);
for (intk=0;k<temp.size();k++){
if(temp.get(k)!=i&&temp.get(k)!=j){
ArrayList<Integer>tempAns=new ArrayList<Integer>();
tempAns.add(num[i]);
tempAns.add(num[j]);
tempAns.add(-sum);
qsort(tempAns,0,2);
StringtempS=tempAns.get(0)+" "+tempAns.get(1)+" "+tempAns.get(2);
if(!hashAns.contains(tempS)){
hashAns.add(tempS);
ans.add(tempAns);
}
break;
}
}
}
}
}
return ans;
}
private void qsort(ArrayList<Integer> tempArr, int x, int y) {
inti=x;
intj=y;
intt=tempArr.get((i+j)/2);
do{
while(tempArr.get(i)<t){
i++;
}
while(tempArr.get(j)>t){
j--;
}
if(i<=j){
inttemp=tempArr.get(i);
tempArr.set(i,tempArr.get(j));
tempArr.set(j,temp);
i++;
j--;
}
}while(i<=j);
if(j>x){
qsort(tempArr,x,j);
}
if(i<y){
qsort(tempArr,i,y);
}
}
}