給定兩個數組,編寫一個函數來計算它們的交集。java
Given two arrays, write a function to compute their intersection.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]
說明:app
Note:函數
進階:優化
Follow up:指針
暴力解題就不說了。code
哈希表:排序
利用哈希映射求得其中一個數組每一個數字出現的頻次。遍歷另外一個數組,每遇到相同數字,其存儲頻次減一,若頻次爲 0,則移出哈希映射。如:
輸入 nums1 = [4, 9, 5], nums2 = [9, 4, 9, 8, 4 } 計算 nums1 頻次: { 4:1, 9:1, 5:1 },Key = {4 , 9, 5 } 遍歷 nums2: 9 存在於 Key,9 頻次 -1 爲 0,9 移出 HashMap:{ 4:1, 5:1 } 4 存在於 Key,4 頻次 -1 爲 0,4 移出 HashMap:{ 5:1 } 9 不存在於 Key,跳過 8 不存在於 Key,跳過 ... 輸出:{9, 4}
雙指針:
先把兩個數組排序,定義兩個指針 i, j
,移動指針
如:
輸入 nums1 = [ 4, 9, 5 ], nums2 = [ 9, 4, 9, 8, 4 ] 排序 nums1 = [ 4, 5, 9 ], nums2 = [ 4, 4, 8, 9, 9 ] 雙指針遍歷:[ 4, 5, 9],[ 4, 4, 8, 9, 9 ] ^ ^ 4 = 4, 存入 res = [4], 移動雙指針: [ 4, 5, 9],[ 4, 4, 8, 9, 9 ] ^ ^ 5 > 4, 移動指向 4 的指針:[ 4, 5, 9],[ 4, 4, 8, 9, 9 ] ^ ^ 5 < 8, 移動指向 5 的指針:[ 4, 5, 9],[ 4, 4, 8, 9, 9 ] ^ ^ 9 > 8, 移動指向 8 的指針:[ 4, 5, 9],[ 4, 4, 8, 9, 9 ] ^ ^ 9 = 9, 存入 res = [4, 9], 移動雙指針: [ 4, 5, 9 ],[ 4, 4, 8, 9, 9 ] ^ ^ 超過 nums1 長度,結束,返回 res
回答進階問題:
Java:
class Solution { public int[] intersect(int[] nums1, int[] nums2) { HashMap<Integer, Integer> map = new HashMap<>(); List<Integer> list = new ArrayList<>();//動態數組 for (Integer num : nums1) map.put(num, map.getOrDefault(num, 0) + 1);//統計元素出現頻次 for (Integer num : nums2) {//遍歷另外一個數組 if (map.containsKey(num)) { int tmp = map.get(num)-1;//頻次減一 if (tmp == 0) map.remove(num);//頻次爲 0 時,移出 HashMap else map.put(num, tmp);//不然更新頻次 list.add(num);//加入動態數組 } } //轉爲數組並返回 int size=list.size(); int[] res = new int[size]; for (int i = 0; i < size; i++) res[i] = list.get(i); return res; } }
Python:
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: count = dict(collections.Counter(nums1))# 自帶庫統計元素出現頻次,並轉爲 Dict 類型 res = [] for num in nums2:# 遍歷另外一個數組 if num in count: count[num] -= 1# 詞頻減一 res.append(num) if count[num] <= 0:# 詞頻爲 0 時,移出字典 count.pop(num) return res
Java:
class Solution { public int[] intersect(int[] nums1, int[] nums2) { List<Integer> list = new ArrayList<>(); Arrays.sort(nums1);//排序數組 Arrays.sort(nums2); int i = 0, j = 0;//定義指針 while (i < nums1.length && j < nums2.length) { if (nums1[i] < nums2[j]) i++;//移動較小數的指針 else if (nums1[i] > nums2[j]) j++;//移動較小數的指針 else { //兩數相等則爲交集,存入動態數組,移動雙指針 list.add(nums1[i]); i++; j++; } } //轉爲數組並返回 int[] res = new int[list.size()]; for (int k = 0; k < list.size(); k++) res[k] = list.get(k); return res; } }
Python:
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: i, j, nums1_size, nums2_size = 0, 0, len(nums1), len(nums2)# 定義指針,計算數組長度 nums1, nums2, res = sorted(nums1), sorted(nums2), []# 排序數組,初始化返回數組 res while i < nums1_size and j < nums2_size:# 循環條件爲指針不溢出 if nums1[i] < nums2[j]:# 移動數值較小的指針 i += 1 elif nums1[i] > nums2[j]:# 移動數值較小的指針 j += 1 else: res.append(nums1[i])# 數值相等,則爲交集,移動雙指針 i += 1 j += 1 return res
歡迎關注微.信..公.衆.號: 愛寫Bug