[LeetCode] 350. Intersection of Two Arrays II 两个数组相交II
Given two arrays, write a function to compute their intersection.
Example 1:
Input: nums1 = [1,2,2,1], nums2 = [2,2]
Output: [2,2]
Example 2:
Input: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
Output: [4,9]
Note:
- Each element in the result should appear as many times as it shows in both arrays.
- The result can be in any order.
Follow up:
- What if the given array is already sorted? How would you optimize your algorithm?
- What if nums1's size is small compared to nums2's size? Which algorithm is better?
- What if elements of nums2 are stored on disk, and the memory is limited such that you cannot load all elements into the memory at once?
解法1:Hashmap
解法2:双指针
Python:
class Solution(object): def intersect(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: List[int] """ if len(nums1) > len(nums2): return self.intersect(nums2, nums1) lookup = collections.defaultdict(int) for i in nums1: lookup[i] += 1 res = [] for i in nums2: if lookup[i] > 0: res += i, lookup[i] -= 1 return res
# If the given array is already sorted, and the memory is limited, and (m << n or m >> n). # Time: O(min(m, n) * log(max(m, n))) # Space: O(1) # Binary search solution. class Solution(object): def intersect(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: List[int] """ if len(nums1) > len(nums2): return self.intersect(nums2, nums1) def binary_search(compare, nums, left, right, target): while left < right: mid = left + (right - left) / 2 if compare(nums[mid], target): right = mid else: left = mid + 1 return left nums1.sort(), nums2.sort() # Make sure it is sorted, doesn't count in time. res = [] left = 0 for i in nums1: left = binary_search(lambda x, y: x >= y, nums2, left, len(nums2), i) if left != len(nums2) and nums2[left] == i: res += i, left += 1 return res
# If the given array is already sorted, and the memory is limited or m ~ n. # Time: O(m + n) # Soace: O(1) # Two pointers solution. class Solution(object): def intersect(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: List[int] """ nums1.sort(), nums2.sort() # Make sure it is sorted, doesn't count in time. res = [] it1, it2 = 0, 0 while it1 < len(nums1) and it2 < len(nums2): if nums1[it1] < nums2[it2]: it1 += 1 elif nums1[it1] > nums2[it2]: it2 += 1 else: res += nums1[it1], it1 += 1 it2 += 1 return res
# If the given array is not sorted, and the memory is limited. # Time: O(max(m, n) * log(max(m, n))) # Space: O(1) # Two pointers solution. class Solution(object): def intersect(self, nums1, nums2): """ :type nums1: List[int] :type nums2: List[int] :rtype: List[int] """ nums1.sort(), nums2.sort() # O(max(m, n) * log(max(m, n))) res = [] it1, it2 = 0, 0 while it1 < len(nums1) and it2 < len(nums2): if nums1[it1] < nums2[it2]: it1 += 1 elif nums1[it1] > nums2[it2]: it2 += 1 else: res += nums1[it1], it1 += 1 it2 += 1 return res
C++:
// If the given array is not sorted and the memory is unlimited. // Time: O(m + n) // Space: O(min(m, n)) // Hash solution. class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { if (nums1.size() > nums2.size()) { return intersect(nums2, nums1); } unordered_map<int, int> lookup; for (const auto& i : nums1) { ++lookup[i]; } vector<int> result; for (const auto& i : nums2) { if (lookup[i] > 0) { result.emplace_back(i); --lookup[i]; } } return result; } };
C++:
// If the given array is already sorted, and the memory is limited, and (m << n or m >> n). // Time: O(min(m, n) * log(max(m, n))) // Space: O(1) // Binary search solution. class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { if (nums1.size() > nums2.size()) { return intersect(nums2, nums1); } // Make sure it is sorted, doesn't count in time. sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); vector<int> result; auto it = nums2.cbegin(); for (const auto& i : nums1) { it = lower_bound(it, nums2.cend(), i); if (it != nums2.end() && *it == i) { result.emplace_back(*it++); } } return result; } };
C++:
// If the given array is already sorted, and the memory is limited or m ~ n. // Time: O(m + n) // Soace: O(1) // Two pointers solution. class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { vector<int> result; // Make sure it is sorted, doesn't count in time. sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); auto it1 = nums1.cbegin(), it2 = nums2.cbegin(); while (it1 != nums1.cend() && it2 != nums2.cend()) { if (*it1 < *it2) { ++it1; } else if (*it1 > *it2) { ++it2; } else { result.emplace_back(*it1); ++it1, ++it2; } } return result; } };
C++:
// If the given array is not sorted, and the memory is limited. // Time: O(max(m, n) * log(max(m, n))) // Space: O(1) // Two pointers solution. class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { vector<int> result; // O(max(m, n) * log(max(m, n))) sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end()); auto it1 = nums1.cbegin(), it2 = nums2.cbegin(); while (it1 != nums1.cend() && it2 != nums2.cend()) { if (*it1 < *it2) { ++it1; } else if (*it1 > *it2) { ++it2; } else { result.emplace_back(*it1); ++it1, ++it2; } } return result; } };
类似题目:
[LeetCode] 349. Intersection of Two Arrays 两个数组相交
[LeetCode] 160. Intersection of Two Linked Lists 求两个链表的交集