1、排序+双指针
交集:
用两个指针分别指向两个数组的头部。如果其中一个元素比另一个小,后移小的那个数组的指针;如果相等,那么把该元素添加到交集里,同时后移两个数组的指针。一直这样操作下去,直到有一个指针超过数组范围。
public List intersection(int[] a, int[] b){//a和b已经排好序
List<Integer> result=new ArrayList<>();
int i=0,j=0;
while(i<a.length && j<b.length){
if(a[i]<b[j]){
i++;
}else if(a[i]>b[j]){
j++;
}else{
result.add(a[i]);
i++;
j++;
}
}
return result;
}
并集:
用两个“指针”分别指向两个数组的头部。如果其中一个数组的元素比另一个小,把该元素添加到并集里,后移小的那个数组的指针;如果相等,那么把该元素添加到并集里,同时后移两个数组的指针。一直这样操作下去,直到有一个指针超过数组范围。将两个数组中没有遍历完的那个数组的其余元素全部添加进并集里。
public List union(int[] a, int[] b){//a和b已经排好序
List<Integer> result=new ArrayList<>();
int i=0,j=0;
while(i<a.length && j<b.length){
if(a[i]<b[j]){
result.add(a[i]);
i++;
}else if(a[i]>b[j]){
result.add(b[j]);
j++;
}else{
result.add(a[i]);
i++;
j++;
}
}
while(i<a.length){
result.add(a[i]);
i++;
}
while(j<b.length){
result.add(b[j]);
j++;
}
return result;
}
时间复杂度:
O(n)=O(m+n) //m为第一个数组的长度,n为第二个数组的长度
2、哈希表
交集:
①建立一个哈希表(HashMap),其键(KEY)表示集合中数字的值,其值(VALUE)表示集合中数字出现的次数
②遍历集合A,将集合中的每个数字(KEY)插入哈希表,每个数字的出现次数(VALUE)设置为1
③遍历集合B,对于集合中的每个数字:
如果哈希表中已经存在该数字,将对应的VALUE改为2
如果哈希表中不存在该数字,忽略
④遍历哈希表,输出VALUE为2的数字,即得到A和B的交集
public List intersection(int[] a, int[] b){
List<Integer> result=new ArrayList<>();
HashMap<Integer,Integer> hash=new HashMap<>();
for(int i=0;i<a.length;i++){
hash.put(a[i],1);
}
for(int j=0;j<b.length;j++){
if(hash.containsKey(b[j])){
hash.put(b[j],2);
}
}
Iterator<Integer> iter=hash.keySet().iterator();
while(iter.hasNext()){
int key=iter.next();
if(hash.get(key)!=1){
result.add(key);
}
}
return result;
}
并集:
①建立一个哈希集(HashSet)
②遍历集合A,将集合中的每个数字(KEY)插入哈希集
③遍历集合B,对于集合中的每个数字:
如果哈希集中已经存在该数字,忽略
如果哈希集中不存在该数字,将这个数字插入哈希集
④遍历哈希集,即为A和B的并集
public HashSet union(int[] a, int[] b){
HashSet<Integer> set=new HashSet<>();
for(int i=0;i<a.length;i++){
set.add(a[i]);
}
for(int j=0;j<b.length;j++){
if(!set.contains(b[j])){
set.add(b[j]);
}
}
return set;
}
时间复杂度:
O(n)=O(max(m,n)) //m为第一个数组的长度,n为第二个数组的长度