1. 程式人生 > 實用技巧 >兩個陣列的交集【349】

兩個陣列的交集【349】

給定兩個陣列,編寫一個函式來計算它們的交集。

示例 1:

輸入:nums1 = [1,2,2,1], nums2 = [2,2]
輸出:[2]

示例 2:

輸入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
輸出:[9,4]

一.雙集合

思路:

將兩個陣列分別放入兩個set集合中,比較一個集合是否包含另一個集合的欄位,如果包含就放入集合中
class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {

        List<Integer> list = new ArrayList();

        Set<Integer> num1Set = new HashSet();
        Set<Integer> num2Set = new HashSet();

        for(int i = 0; i < nums1.length; i++){
            num1Set.add(nums1[i]);
        }

        for(int i = 0; i < nums2.length; i++){
            num2Set.add(nums2[i]);
        }
         for(int key: num1Set){
            if(num2Set.contains(key)){
                list.add(key);
            }
        }

        int num3[] = list.stream().mapToInt(Integer::valueOf).toArray();

        return  num3;
        
    }
}

//大佬的寫法:
public int[] intersection(int[] nums1, int[] nums2) {
    Set<Integer> set = Arrays.stream(nums1).boxed().collect(Collectors.toSet());
    return Arrays.stream(nums2).distinct().filter(set::contains).toArray();
}

複雜度分析

  • 時間複雜度:O(m+n),其中 m 和 n 分別是兩個陣列的長度。使用兩個集合分別儲存兩個陣列中的元素需要 O(m+n) 的時間,遍歷較小的集合並判斷元素是否在另一個集合中需要O(min(m,n)) 的時間,因此總時間複雜度是 O(m+n)。
  • 空間複雜度:O(m+n),其中 m 和 n 分別是兩個陣列的長度。空間複雜度主要取決於兩個集合。

二.排序 + 雙指標

思路:

首先對兩個陣列進行排序,然後使用兩個指標遍歷兩個陣列。可以預見的是加入答案的陣列的元素一定是遞增的,為了保證加入元素的唯一性,我們需要額外記錄變數 pre表示上一次加入答案陣列的元素。
初始時,兩個指標分別指向兩個陣列的頭部。每次比較兩個指標指向的兩個陣列中的數字,如果兩個數字不相等,則將指向較小數字的指標右移一位,如果兩個數字相等,且該數字不等於 pre ,
將該數字新增到答案並更新 pre 變數,同時將兩個指標都右移一位。當至少有一個指標超出陣列範圍時,遍歷結束。

程式碼:

class Solution {
    public int[] intersection(int[] nums1, int[] nums2) {
        Arrays.sort(nums1);
        Arrays.sort(nums2);
        int length1 = nums1.length, length2 = nums2.length;
        int[] intersection = new int[length1 + length2];
        int index = 0, index1 = 0, index2 = 0;
        while (index1 < length1 && index2 < length2) {
            int num1 = nums1[index1], num2 = nums2[index2];
            if (num1 == num2) {
                // 保證加入元素的唯一性
                if (index == 0 || num1 != intersection[index - 1]) {
                    intersection[index++] = num1;
                }
                index1++;
                index2++;
            } else if (num1 < num2) {
                index1++;
            } else {
                index2++;
            }
        }
        return Arrays.copyOfRange(intersection, 0, index);
    }
}

複雜度分析

  • 時間複雜度:O(mlogm+nlogn),其中 m 和 n 分別是兩個陣列的長度。對兩個陣列排序的時間複雜度分別是 O(mlogm) 和 O(nlogn),雙指標尋找交集元素的時間複雜度是 O(m+n),因此總時間複雜度是 O(mlogm+nlogn)。

  • 空間複雜度:O(logm+logn),其中 m 和 n 分別是兩個陣列的長度。空間複雜度主要取決於排序使用的額外空間。