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 <= 10000 <= 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
nums1is larger thannums2and swaps them if necessary. This check isO(1). - The potential recursive call
intersect(nums2, nums1)only happens once, ensuring thatnums1is the smaller or equal-sized array. - The loop
for (const int num : nums1)iterates throughnums1and builds the hash mapcount. This loop runs inO(m)time, wheremis the size ofnums1. - The loop
for (const int num : nums2)iterates throughnums2and checks for intersections. This loop runs inO(n)time, wherenis the size ofnums2. - Therefore, the overall time complexity is
O(m + n).
Space Complexity:
- The hash map
countstores at mostmkey-value pairs (wheremis the size ofnums1). The space complexity for the hash map isO(m). - The result vector
resultstores 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)sortsnums1inO(m \log m)time, wheremis the size ofnums1.ranges::sort(nums2)sortsnums2inO(n \log n)time, wherenis the size ofnums2.- The
whileloop iterates through bothnums1andnums2until 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
nums1andnums2in place does not require additional space, so the space complexity for sorting isO(1)in terms of auxiliary space. - The result vector
resultstores the intersection elements. In the worst case, this could store all elements of the smaller array (i.e.,nums1ornums2), 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)sortsnums1inO(m \log m)time, wheremis the size ofnums1.ranges::sort(nums2)sortsnums2inO(n \log n)time, wherenis the size ofnums2.- The for loop iterates through
nums1and performs a binary search for each element. This loop runs inO(m)time, wheremis the size ofnums1. - The binary search runs in
O(\log n)time for each element innums1, wherenis the size ofnums2. - Therefore, the overall time complexity is
O(m \log m + n \log n).
Space Complexity:
- Sorting
nums1andnums2in 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)).