1. 題目描述
給定兩個數組nums1和nums2,返回它們的交集。輸出結果中的每個元素一定是唯一的。我們可以不考慮輸出結果的順序。
示例1:
輸入:nums1 = [1,2,2,1], nums2 = [2,2]
輸出:[2]
題目條件:
- 1 <= nums1.length, nums2.length <= 1000
- 0 <= nums1[i], nums2[i] <= 1000
2. 解題思路
2.1 數組比較法(適用于題目條件限制了數組范圍和元素范圍的情況)
- 定義一個空數組cuontnums用于存儲較短的那個數組中元素出現次數
- 遍歷另一個數組的元素,看是否在countnums中存在,如果存在則放入結果數組,并把countnums中對應元素清零(防止重復)
- 返回結果數組
2.2 哈希表法(適用于任意整數元素范圍的情況)
哈希表相比固定數組的優勢是哈希表可以處理任意整數,而不僅僅是0到1000之間的數,這樣更靈活。原來的方法有潛在越界風險,哈希表能解決這個問題。但同時,帶來了一定的復雜度,這一部分用C++中的unorder_set來實現,如果用C語言則需要導入第三方庫(如 uthash),因為C語言沒有原生的unordered_set。
哈希表實現邏輯如下:
- 定義哈希表結構體:存儲數字及其出現次數。
- 統計 nums1 的元素:將 nums1 中的數字插入哈希表,記錄出現次數。
- 遍歷 nums2 檢查交集:若數字存在于哈希表中,則加入結果數組,并根據需求減少計數(支持重復)或刪除鍵(去重)。
- 動態管理內存:釋放哈希表內存
3. 代碼實現(C語言)
3.1 數組比較法
int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize) {int countnums[1001] = {0}; // 統計nums1中數字出現的次數(題目條件:元素值范圍0~1000)int lesssize = nums1Size < nums2Size ? nums1Size : nums2Size; //找到更短的數組,這是最大交集長度int *result = (int*)calloc(lesssize, sizeof(int)); //動態分配內存空間并初始化為0int resultindex = 0;for(int i = 0; i < nums1Size; i++){countnums[nums1[i]]++; //遍歷nums1,統計每個數字出現的次數到countnums1中}for(int i = 0; i < nums2Size; i++){//遍歷nums2,若 nums2[i] 在 nums1 中存在(計數>0),//如果存在,就將該數字添加到結果數組,并增加結果索引//同時將countnums1對應的位置設為0,避免重復添加。if(countnums[nums2[i]] > 0){result[resultindex] = nums2[i];resultindex++;countnums[nums2[i]] = 0; }}*returnSize = resultindex;return result;
}
有一個點說明的是,如果不考慮去除交集中的重復,countnums[nums2[i]] = 0改為 countnums[nums2[i]]- - 即可。
3.2哈希表法
C++實現
class Solution {
public:vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {unordered_set<int> result_set; // 存放結果,之所以用set是為了給結果集去重unordered_set<int> nums_set(nums1.begin(), nums1.end());for (int num : nums2) {// 發現nums2的元素 在nums_set里又出現過if (nums_set.find(num) != nums_set.end()) {result_set.insert(num);}}return vector<int>(result_set.begin(), result_set.end());}
};