求两个集合的交集和并集

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为第二个数组的长度

发布了22 篇原创文章 · 获赞 7 · 访问量 4474

猜你喜欢

转载自blog.csdn.net/lucky_jiexia/article/details/104435878