技术交流可以加:
本人微信:xcg852390212
本人qq:852390212
学习交流qq群1(已满): 962535112
学习交流qq群2: 780902027
两个数组的交集
给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [9,4]
说明:
- 输出结果中的每个元素一定是唯一的。
- 我们可以不考虑输出结果的顺序。
解答
方法1
将数组nums1
的元素放入一个set
中,然后遍历nums2
的元素nums2[i]
,判断它是否在set
中,如果在set
中,则说明这个元素是交集的部分,将它加入结果中。
设nums1
的大小为m
,数组nums2
的大小为n
- 时间复杂度:O(m + n)
- 空间复杂度:O(m)
C++代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
if(nums1.empty() || nums2.empty())
return vector<int>();
unordered_set<int> st;
for(auto a : nums1)
st.insert(a);
vector<int> res;
for(int a : nums2)
{
if(st.count(a) > 0)
{
res.push_back(a);
st.erase(a);
}
}
return res;
}
};
Python代码
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
s = set()
res = []
for a in nums1:
s.add(a)
for a in nums2:
if a in s:
res.append(a)
s.remove(a)
return res
方法2:排序 +双指针
先将nums1
和nums2
排序(从小到大排序),维护一个set
存放交集元素,定义两个指针p1
和p2
分别从nums1
和nums2
出发,处理情况如下:
- 如果
nums1[p1] == nums2[p2]
,则将numns[p1]
放入set
,同时++p1
,++p2
; - 否则,
nums1[p1] < nums2[p2] ? ++p1 : ++p2
。
直到p1
或p2
到达数组尾部。
最后将set
中的元素放入结果数组中即可。
设nums1
的大小为m
,数组nums2
的大小为n
- 时间复杂度:O(m log m + n log n)
- 空间复杂度:O(max(m,n))
C++代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());
vector<int> res;
set<int> st;
int p1 = 0,p2 = 0;
while(p1 < nums1.size() && p2 < nums2.size())
{
if(nums1[p1] == nums2[p2])
{
st.insert(nums1[p1]);
++p1;
++p2;
}
else{
nums1[p1] < nums2[p2] ? ++p1 : ++p2;
}
}
for(auto a : st) res.push_back(a);
return res;
}
};
Python代码
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1.sort()
nums2.sort()
i = 0
s = set()
res = []
i,j = 0,0
while i < len(nums1) and j < len(nums2):
if nums1[i] == nums2[j]:
s.add(nums1[i])
i += 1
j += 1
elif nums1[i] > nums2[j]:
j += 1
else:
i += 1
for a in s:
res.append(a)
return res
方法3
现将nums1
从小到大排序,遍历数组nums2
的每一个元素nums2[i]
,同时在nums1
中二分查找nums2[i]
,如果能找到nums2[i]
,则将它加入set
中;否则,跳过。最后,将set
中的元素放入结果数组即可。
设nums1
的大小为m
,数组nums2
的大小为n
- 时间复杂度:O((m + n) log m)
- 空间复杂度:O(min(m,n))
C++代码
class Solution {
public:
bool binarySearch(const vector<int>& vec,int target)
{
int l = 0,r = vec.size() - 1;
while(l <= r)
{
int m = (l + r) / 2;
if(vec[m] < target) l = m+1;
else if(vec[m] > target) r = m-1;
else return true;
}
return false;
}
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(),nums1.end());
set<int> st;
vector<int> res;
for(auto a : nums2)
{
if(binarySearch(nums1,a))
st.insert(a);
}
for(auto a : st) res.push_back(a);
return res;
}
};