題目內容
給定兩個數組,編寫一個函數來計算它們的交集。
示例 1:
輸入: nums1 = [1,2,2,1], nums2 = [2,2]
輸出: [2,2]
示例 2:
輸入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
輸出: [4,9]
說明:
- 輸出結果中每個元素出現的次數,應與元素在兩個數組中出現的次數一致。
- 我們可以不考慮輸出結果的順序。
進階:
- 如果給定的數組已經排好序呢?你將如何優化你的算法?
- 如果 nums1 的大小比 nums2 小很多,哪種方法更優?
- 如果 nums2 的元素存儲在磁盤上,磁盤內存是有限的,並且你不能一次加載所有的元素到內存中,你該怎麼辦?
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/intersection-of-two-arrays-ii
題目效率
解法 | 時間複雜度 | 空間複雜度 | 執行用時 |
---|---|---|---|
Ans 1 (Python) | O(n+m) | O(n+m) | 56ms (91.11%) |
Ans 2 (Python) | O(n+m) | O(min(n,m)) | 52ms (96.55%) |
Ans 3 (Python) | O(nlogn+mlogm) | O(1) | 56ms (91.11%) |
LeetCode的Python執行用時隨緣,只要時間複雜度沒有明顯差異,執行用時一般都在同一個量級,僅作參考意義。
解法一(雙哈希表):
【思路】
最直接的,我們會想到使用兩個哈希表,分別存儲兩個數組的值;而後再通過比較兩個哈希表中的值來判斷兩個數組的交集。
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
hashmap1 = {}
hashmap2 = {}
for n in nums1:
if n not in hashmap1:
hashmap1[n] = 1
else:
hashmap1[n] += 1
for n in nums2:
if n in hashmap1:
if n not in hashmap2:
hashmap2[n] = 1
else:
hashmap2[n] += 1
ans = []
for n in hashmap1:
if n in hashmap2:
ans += [n] * min(hashmap1[n], hashmap2[n])
return ans
解法二(單哈希表實現):
【思路】
在解法一種,實際上我們不但對兩個數組分別進行了遍歷,而且還對其中一個映射的哈希表進行了遍歷,時間複雜度較高;另外,我們分別存儲了兩個數組的映射哈希表,空間複雜度也較高。但是,實際上我們在遍歷第二個數組的時候,就已經可以通過和第一個數組的哈希表進行比較得出結果了。
在實際操作中,我們在遍歷第二個數組時,如果發現當前數存在於哈希表中,則可將該數添加到答案中,並在哈希表中減去該數,這樣我們就可以僅對兩個數組各進行一次遍歷就得到結果了。
在生成映射哈希表的選擇時,我們應選擇相對較小的數組,這樣佔用的空間複雜度更小。
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
hashmap = {}
# 選擇較小的一個數組
if len(nums1) > len(nums2):
nums1, nums2 = nums2, nums1
# 將較小的一個數組存入哈希表
for n in nums1:
if n not in hashmap:
hashmap[n] = 1
else:
hashmap[n] += 1
ans = []
for n in nums2:
if n in hashmap and hashmap[n] > 0:
ans.append(n)
hashmap[n] -= 1
return ans
解法三(排序):
【思路】
除以上解法外,我們還可以先將兩個數組排序,並分別使用一個指針進行遍歷來判斷交集。但是,這個方法相較於以上的解法,除需要對兩個數組遍歷外,還需要對兩個數組進行排序,因此時間複雜度更高。
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1.sort()
nums2.sort()
index1 = 0
index2 = 0
ans = []
while index1 <= len(nums1) - 1 and index2 <= len(nums2) - 1:
if nums1[index1] < nums2[index2]:
index1 += 1
elif nums1[index1] > nums2[index2]:
index2 += 1
else:
ans.append(nums1[index1])
index1 += 1
index2 += 1
return ans