LeetCode精講(0350):求兩個數組的交集(保留交集元素出現次數)(Python)

題目內容

給定兩個數組,編寫一個函數來計算它們的交集。

示例 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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章