找出兩個數組的交集

交集是集合里的概念,而集合是不允許有重復元素的,然而數組卻是允許重復元素的。
所以解這道題時要注意去重。

使用HashSet

這無疑是最簡單,最取巧的方法。通過把一個數組放入HashSet中,然后再遍歷第二個數組看元素是否存在于HashSet里即可找出交集,時間復雜度為 O(n) + O(m), n和m為兩個數組的長度

    //使用HashSet
    public static Integer[] find2(int[] arr1, int[] arr2) {
        Set<Integer> resultSet = new HashSet<Integer>();
        
        //HashSet存取的時間復雜度都為O(1) 
        Set<Integer> set = new HashSet<Integer>();
        for(int num : arr1){
            set.add(num);
        }
        for(int num : arr2){
            if(set.contains(num)){
                resultSet.add(num);
            }
        }
        
        return resultSet.toArray(new Integer[resultSet.size()]);
    }

放入一個數組,排序,找相鄰是否相同

  1. 把兩個數組分別去重后,放入一個數組, O(m+n)
  2. 排序 O((m+n) * log2(m+n))
  3. 遍歷,相鄰元素相同即為交集元素 O(m+n)
    //合并成一個數組,排序后遍歷,相鄰相同即為交集元素
    public static Integer[] find3(int[] arr1, int[] arr2) {
        Set<Integer> resultSet = new HashSet<Integer>();
        
        //給兩個數組去重,合并
        Set<Integer> set1 = new HashSet<Integer>();
        for(int num : arr1){
            set1.add(num);
        }
        Set<Integer> set2 = new HashSet<Integer>();
        for(int num : arr2){
            set2.add(num);
        }
        List<Integer> list = new ArrayList<Integer>();
        list.addAll(set1);
        list.addAll(set2);
        Integer[] newArr = list.toArray(new Integer[list.size()]);
        
        //排序
        Arrays.sort(newArr);
        
        //遍歷一遍,相鄰相同即是交集
        Integer previous = null;
        for(Integer current : newArr){
            if(previous == current){
                resultSet.add(previous);
            }
            previous = current;
        }
        
        return resultSet.toArray(new Integer[resultSet.size()]);
    }

分別排序,交叉查找

  1. 分別排序, O(n*log2n) + O(m*log2m)
  2. 交叉查找, O(n+m)
    //對兩個數組排序,然后交叉查找
    public static Integer[] find1(int[] arr1, int[] arr2) {
        //排序
        Arrays.sort(arr1);
        Arrays.sort(arr2);
        
        Set<Integer> resultSet = new HashSet<Integer>();

        int indexOfArr1 = 0;
        int indexOfArr2 = 0;
        while (indexOfArr1 < arr1.length && indexOfArr2 < arr2.length) {
            //從數組1中取出一個元素,逐一和數組2的元素比較,直到數組2的元素大于這個取出的元素
            int benchMarkInArr1 = arr1[indexOfArr1];
            for ( ; indexOfArr2 < arr2.length; indexOfArr2++) {
                if(benchMarkInArr1 == arr2[indexOfArr2]){
                    resultSet.add(benchMarkInArr1);
                }else if(benchMarkInArr1 < arr2[indexOfArr2]){
                    break;
                }
            }
            //數組1坐標后移一位
            indexOfArr1 = indexOfArr1 + 1;
            if(indexOfArr1 >= arr1.length || indexOfArr2 >= arr2.length){
                //任意數組已經遍歷到頭,那不再可能有更多的交集元素
                break;
            }
            //從數組2中取出一個元素,逐一和數組1的元素比較,直到數組1的元素大于這個取出的元素
            int benchMarkInArr2 = arr2[indexOfArr2];
            for ( ; indexOfArr1 < arr1.length; indexOfArr1++) {
                if(benchMarkInArr2 == arr1[indexOfArr1]){
                    resultSet.add(benchMarkInArr2);
                }else if(benchMarkInArr2 < arr1[indexOfArr1]){
                    break;
                }
            }
        }

        return resultSet.toArray(new Integer[resultSet.size()]);
    }

比起上一種解法,O(n*log2n) + O(m*log2m) 應該小于 O((m+n) * log2(m+n)),所以時間復雜度會低一些

代碼

Code

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • 1.插入排序—直接插入排序(Straight Insertion Sort) 基本思想: 將一個記錄插入到已排序好...
    依依玖玥閱讀 1,352評論 0 2
  • 一、 單項選擇題(共71題) 對n個元素的序列進行冒泡排序時,最少的比較次數是( )。A. n ...
    貝影閱讀 9,424評論 0 10
  • 面試中常用的幾個基本算法整理記錄(二) 無意中看到了面試中的 10 大排序算法總結原文地址記錄一下,方便查找。 查...
    190CM閱讀 1,877評論 1 12
  • 【打卡始于2017.10.14持續(xù)于2017.11.13】 【知~學習】 《六項精進》讀3遍, 《大學》讀0遍。 ...
    lovelyfener閱讀 162評論 0 1
  • 2016年7月6日 我們的故事~泰興! 大香腸真心好吃,應該說和你在一起的每分每秒,都很好呢,吃什么玩什么,都無所...
    夜夏未空閱讀 250評論 0 0

友情鏈接更多精彩內容