題目:給定兩個整數陣列 nums1 和 nums2,回傳它們的交集(intersection)
- 每個元素在結果中出現的次數,應等於它在兩個陣列中出現的次數最小值
- 結果可以以任意順序回傳
-
解法一

- 簡單直觀,但效率差
- 遍歷第一個陣列,每個元素去第二個陣列找有沒有出現
- 找到就加入答案,並從第二個陣列刪掉一次(避免重複)
註解
- if num in nums2 → 判斷是否存在於另一個陣列
- nums2.remove(num) → 每次找到就刪掉一個,確保數量正確
- 時間複雜度:O(n*m),因為 in 與 remove 都是 O(m)
理解
- 就像兩個班級點名:
(1)A 班學生名單(nums1)逐個讀名字
(2)去 B 班(nums2)找有沒有這個人
(3)找到就記錄一次,並在 B 班劃掉一個名字,避免重複計算
解法二

- 效率高
- Hash Map(計數法)
- 用一個字典(dict / Counter)記錄第一個陣列中每個數字出現的次數
- 再遍歷第二個陣列,每次遇到還有剩餘次數的數字,就加入答案,並把次數減一
註解
- Counter(nums1) → 統計 nums1 中每個元素出現次數
- 遍歷 nums2,如果還有剩餘次數(count[num] > 0),就放入答案並扣掉一次
- 時間 O(n+m),空間 O(n)
理解
- 想像:
(1)先把 A 班的學生名單做成「點名次數表」
(2)再去 B 班找人,每找到一個,就在表上劃掉一次
(3)最後拿到正確的「交集名單」
解法三

- 排序 + 雙指針(Two Pointers)
- 先把兩個陣列排序
- 用兩個指針分別遍歷 nums1 和 nums2
註解
- sort() → 先排序,讓相同數字集中
- i、j → 分別是兩個陣列的指針
- 相等 → 加入答案,兩指針一起往前
- 不相等 → 移動較小的指針
理解
- 就像有兩個名單:
(1)把名單都按照學號排序
(2)用兩隻手指比對,如果相同 → 記下來
(3)如果一邊比較小,就讓小的那邊往下走
(4)直到其中一個名單走完