[Algo] Find Intersection of Two Sets 找交集

Find Intersection of Two Sets

暴力法

複雜度

時間 O(NM) 空間 O(1)數組

思路

暴力解法,對於每一個在集合1中的元素,咱們遍歷一遍集合2看看是否存在,若是存在則是Intersection。指針

代碼

public List<Integer> findByBruteForce(int[] arr1, int[] arr2){
    List<Integer> res = new LinkedList<Integer>();
    for(int i = 0; i < arr1.length; i++){
        for(int j = 0; j < arr2.length; j++){
            if(arr1[i] == arr2[j]){
                res.add(arr1[i]);
            }
        }
    }
    return res;
}

統一排序法

複雜度

時間 O((M+N)log(M+N)) 空間 O(M+N)code

思路

將兩個集合合併起來排序,這樣若是排序後的數組中有兩個相同的元素,說明就是Intersection。排序

代碼

public List<Integer> findBySortTogether(int[] arr1, int[] arr2){
    List<Integer> res = new LinkedList<Integer>();
    int[] all = new int[arr1.length + arr2.length];
    System.arraycopy(arr1, 0, all, 0, arr1.length);
    System.arraycopy(arr2, 0, all, arr1.length, arr2.length);
    Arrays.sort(all);
    for(int i = 0; i < all.length - 1; i++){
        if(all[i] == all[i + 1]){
            res.add(all[i]);
            i++;
        }
    }
    return res;
}

排序歸併法

複雜度

時間 O(MlogM+NlogN) 空間 O(1)get

思路

將兩個集合分別排序,用兩個指針分別指向各自最小的元素。而後比較他們各自最小的元素,若是這兩個元素相同,則加入結果中,並將兩個指針都加1。不然哪一個元素較小,則將其指針加1。io

arr1: 1, 2, 8, 10 ==> arr1: 2, 8, 10 ==> arr1: 8, 10    ==> arr1: 8, 10 ==> ...
arr2: 1, 3, 9, 10     arr2: 3, 9, 10     arr2: 3, 9, 10     arr2: 9, 10
res:  1               res:  1            res:  1            res:  1

代碼

public List<Integer> findBySortingAndMerge(int[] arr1, int[] arr2){
    Arrays.sort(arr1);
    Arrays.sort(arr2);
    List<Integer> res = new LinkedList<Integer>();
    int i = 0, j = 0;
    while(i < arr1.length && j < arr2.length){
        if (arr1[i] == arr2[j]){
            res.add(arr1[i]);
            i++;
            j++;
        } else if (arr1[i] < arr2[j]){
            i++;
        } else if (arr1[i] > arr2[j]){
            j++;
        }
    }
    return res;
}

排序二分搜索

複雜度

時間 Min(O(MlogN+NlogN), O(NlogM+MlogM)) 空間 O(1)List

思路

將較短的那個集合排序,而後對於較長的集合中每個元素,都在較短的集合中二分搜索相應的元素。若是找到則加入結果中。之因此選擇對較短的集合二分搜索,是由於排序須要NlogN的時間,若是對較長數組排序,假設N>M,則時間複雜度是NlogN+MlogN,而對較短數組排序,時間爲MlogM+NlogM,顯然(M+N)logN > (M+N)logM搜索

代碼

public List<Integer> findByBinarySearch(int[] arr1, int[] arr2){
    List<Integer> res = new LinkedList<Integer>();
    if(arr1.length > arr2.length){
        int[] tmp = arr1;
        arr1 = arr2;
        arr2 = tmp;
    }
    Arrays.sort(arr1);
    for(int i = 0;i < arr2.length; i++){
        if(binarySearch(arr1, arr2[i])){
            res.add(arr2[i]);
        }
    }
    return res;
}

private boolean binarySearch(int[] arr, int target){
    int min = 0, max = arr.length - 1;
    while(min <= max){
        int mid = min + (max - min) / 2;
        if(arr[mid] == target){
            return true;
        } else if (arr[mid] > target) {
            max = mid - 1;
        } else {
            min = mid + 1;
        }
    }
    return false;
}

哈希表法

複雜度

時間 O(N) 空間 O(N)遍歷

思路

將第一個集合中的元素加入一個哈希表中,而後過一遍第二個集合,看是否存在於第一個集合中,由於用了哈希,因此總時間只要O(N)。map

代碼

public List<Integer> findByHashmap(int[] arr1, int[] arr2){
    List<Integer> res = new LinkedList<Integer>();
    HashSet<Integer> set = new HashSet<Integer>();
    for(int i = 0; i < arr1.length; i++){
        set.add(arr1[i]);
    }
    for(int i = 0; i < arr2.length; i++){
        if(set.contains(arr2[i])){
            res.add(arr2[i]);
        }
    }
    return res;
}
相關文章
相關標籤/搜索