Given two integer arrays nums1
and nums2
, return an array of their intersection. Each element in the result must appear as many times as it shows in both arrays and you may return the result in any order.
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] Explanation: [9,4] is also accepted.
Constraints:
1 <= nums1.length, nums2.length <= 1000
0 <= nums1[i], nums2[i] <= 1000
Approach 01:
-
C++
-
Python
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { if (nums1.size() > nums2.size()){ return intersect(nums2, nums1); } vector<int> result; unordered_map<int, int> count; for (const int num : nums1){ ++count[num]; } for (const int num : nums2){ if (const auto it = count.find(num); it != count.cend() && it->second-- > 0){ result.push_back(num); } } return result; } };
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: if len(nums1) > len(nums2): return self.intersect(nums2, nums1) result = [] count = collections.Counter(nums1) for num in nums2: if count[num] > 0: result.append(num) count[num] -= 1 return result
Time Complexity:
- The function checks if
nums1
is larger thannums2
and swaps them if necessary. This check isO(1)
. - The potential recursive call
intersect(nums2, nums1)
only happens once, ensuring thatnums1
is the smaller or equal-sized array. - The loop
for (const int num : nums1)
iterates throughnums1
and builds the hash mapcount
. This loop runs inO(m)
time, wherem
is the size ofnums1
. - The loop
for (const int num : nums2)
iterates throughnums2
and checks for intersections. This loop runs inO(n)
time, wheren
is the size ofnums2
. - Therefore, the overall time complexity is
O(m + n)
.
Space Complexity:
- The hash map
count
stores at mostm
key-value pairs (wherem
is the size ofnums1
). The space complexity for the hash map isO(m)
. - The result vector
result
stores the intersection elements. In the worst case, this could store all elements of the smaller array (i.e.,nums1
), which would beO(m)
. - Apart from the hash map and result vector, no significant additional space is used.
- Therefore, the overall space complexity is
O(m)
.
Approach 02:
-
C++
-
Python
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { ranges::sort(nums1); ranges::sort(nums2); vector<int> result; int i = 0; // nums1's index int j = 0; // nums2's index while (i < nums1.size() && j < nums2.size()) if (nums1[i] < nums2[j]) { ++i; } else if (nums1[i] > nums2[j]) { ++j; } else { result.push_back(nums1[i]); ++i; ++j; } return result; } };
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: result = [] i = 0 # index for nums1 j = 0 # index for nums2 nums1.sort() nums2.sort() while i < len(nums1) and j < len(nums2): if nums1[i] < nums2[j]: i += 1 elif nums1[i] > nums2[j]: j += 1 else: result.append(nums1[i]) i += 1 j += 1 return result
Time Complexity:
ranges::sort(nums1)
sortsnums1
inO(m \log m)
time, wherem
is the size ofnums1
.ranges::sort(nums2)
sortsnums2
inO(n \log n)
time, wheren
is the size ofnums2
.- The
while
loop iterates through bothnums1
andnums2
until one of them is exhausted. In the worst case, the loop runs for\min(m, n)
iterations. - Each comparison and potential push back operation inside the loop takes constant time,
O(1)
. - Therefore, the overall time complexity is
O(m \log m + n \log n)
.
Space Complexity:
- Sorting
nums1
andnums2
in place does not require additional space, so the space complexity for sorting isO(1)
in terms of auxiliary space. - The result vector
result
stores the intersection elements. In the worst case, this could store all elements of the smaller array (i.e.,nums1
ornums2
), which would beO(\min(m, n))
. - The additional variables
i
,j
, and loop control variables take constant space,O(1)
. - Therefore, the overall space complexity is
O(\min(m, n))
.
Approach 03:
-
C++
-
Python
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { if (nums1.size() > nums2.size()) return intersect(nums2, nums1); vector<int> result; int lowerBound = 0; // the lower bound for the binary search ranges::sort(nums1); ranges::sort(nums2); for (const int num : nums1) { const int i = binarySearch(nums2, lowerBound, num); if (i < nums2.size() && nums2[i] == num) { result.push_back(num); lowerBound = i + 1; } } return result; } private: int binarySearch(vector<int>& nums2, int lo, int target) { int l = lo; int r = nums2.size(); while (l < r) { const int m = (l + r) / 2; if (nums2[m] >= target) r = m; else l = m + 1; } return l; } };
class Solution: def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]: if len(nums1) > len(nums2): return self.intersect(nums2, nums1) result = [] lower_bound = 0 # lower bound for binary search # Sort both vectors for binary search nums1.sort() nums2.sort() for num in nums1: # Perform binary search on nums2 to find the target element (num) i = self.binary_search(nums2, lower_bound, num) if i < len(nums2) and nums2[i] == num: result.append(num) lower_bound = i + 1 # Update lower bound to avoid duplicates return result def binary_search(self, nums2, l, target): r = len(nums2) # Upper bound (exclusive) while l < r: m = (l + r) // 2 if nums2[m] >= target: r = m else: l = m + 1 return l
Time Complexity:
ranges::sort(nums1)
sortsnums1
inO(m \log m)
time, wherem
is the size ofnums1
.ranges::sort(nums2)
sortsnums2
inO(n \log n)
time, wheren
is the size ofnums2
.- The for loop iterates through
nums1
and performs a binary search for each element. This loop runs inO(m)
time, wherem
is the size ofnums1
. - The binary search runs in
O(\log n)
time for each element innums1
, wheren
is the size ofnums2
. - Therefore, the overall time complexity is
O(m \log m + n \log n)
.
Space Complexity:
- Sorting
nums1
andnums2
in place does not require additional space, so the space complexity for sorting isO(1)
in terms of auxiliary space. - The result vector stores the intersection elements. In the worst case, this could store all elements of the smaller array, which would be
O(\min(m, n))
. - The additional variables take constant space,
O(1)
. - Therefore, the overall space complexity is
O(\min(m, n))
.