给定两个数组,编写一个函数来计算它们的交集。
示例 1:
输入: nums1 = [1,2,2,1], nums2 = [2,2]
输出: [2,2]
示例 2:
输入: nums1 = [4,9,5], nums2 = [9,4,9,8,4]
输出: [4,9]
说明:
输出结果中每个元素出现的次数,应与元素在两个数组中出现的次数一致。
我们可以不考虑输出结果的顺序。
进阶:
如果给定的数组已经排好序呢?你将如何优化你的算法?
如果 nums1 的大小比 nums2 小很多,哪种方法更优?
如果 nums2 的元素存储在磁盘上,磁盘内存是有限的,并且你不能一次加载所有的元素到内存中,你该怎么办?
初步想法:先对nums1,nums2进行排序,再对nums1进行消除重复元素后,再与nums2进行比较相同的返回,但是这种没有考虑到nums1中有的元素只有一个,但是会在nums2中存在两次的问题,导致nums2输出两次如:
1 2 3
1 1 2 3 4
应输出1 2 3 而实际输出却为1 1 2 3
代码如下:
```cpp
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int i,n=0,m=0;
vector<int> resVec;
resVec.clear();
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());//先对两个容器进行排序
for(i=0;i<nums1.size();i++){
if(nums1[i]!=nums1[n]){
n++;
nums1[n]=nums1[i];
}//将nums1进行去重复数字,再用其中数字和nums2中的依次比较
}
for(i=0;i<n+1;i++){
for(int j=0;j<nums2.size();j++){
if(nums1[i]==nums2[j]){
resVec.push_back(nums2[j]);
m++;
}
}
}
return resVec;
}
};
```
经修改后代码如下:
想法是先对数组排序,然后进行对比,中间出现了数组越界问题,因为size得到的是长度,实际上下标只能到达size-1的地方
想法实现:
1 2 3 3 4 n
2 2 3 4 4 5 m
先1 2对比因为1小于2,所以n向后移动一位,2 2相等所以m,n各加一,3大于2 所以m向后移动一位 在这一过程中使用resVec.push_back()将相同的数字插入resVec中
意外情况:
1.没有考虑到一个数只能比较一次,不能与其他数进行重复比较,所以到最后一个数字时,已经无需再次比较直接break即可
```cpp
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int i,n=0,m=0;
vector<int> resVec;
sort(nums1.begin(),nums1.end());
sort(nums2.begin(),nums2.end());//先对两个容器进行排序
while(n<nums1.size() && m<nums2.size()){
if(nums1[n]==nums2[m]){//有相同数字时
resVec.push_back(nums1[n]);//将这个数字返回到resVec中
if(n==nums1.size()-1 &&m==nums2.size()-1){//此时个容器都已经排了最后一个可以直接退出了
break;
}
if(n<nums1.size()-1 && m<nums2.size()-1){//说明两个容器还没到最后一个如果相同下标继续向后移动即可
n++;
m++;
}
else if(n==nums1.size()-1 &&m<nums2.size()-1){//nums1已经到了最后一个数,不必再比较
break;
}
else if(n<nums1.size()-1 &&m==nums2.size()-1){//nums2已经到了最后一个数,不必再比较
break;
}
}
else if(nums1[n]>nums2[m]){//因为已经对nums1,nums2排过序,说明nums2此时的值小于nums1,m向后移动一位
m++;
}
else if(nums1[n]<nums2[m]){
n++;
}
}
return resVec;
}
}
```
如果说数组是有序数组,则我们不必对其进行排序直接比较即可
代码如下:
```cpp
class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
int i,n=0,m=0;
vector<int> resVec;
while(n<nums1.size() && m<nums2.size()){
if(nums1[n]==nums2[m]){//有相同数字时
resVec.push_back(nums1[n]);//将这个数字返回到resVec中
if(n==nums1.size()-1 &&m==nums2.size()-1){//此时个容器都已经排了最后一个可以直接退出了
break;
}
if(n<nums1.size()-1 && m<nums2.size()-1){//说明两个容器还没到最后一个如果相同下标继续向后移动即可
n++;
m++;
}
else if(n==nums1.size()-1 &&m<nums2.size()-1){//nums1已经到了最后一个数,不必再比较
break;
}
else if(n<nums1.size()-1 &&m==nums2.size()-1){//nums2已经到了最后一个数,不必再比较
break;
}
}
else if(nums1[n]>nums2[m]){//因为已经对nums1,nums2排过序,说明nums2此时的值小于nums1,m向后移动一位
m++;
}
else if(nums1[n]<nums2[m]){
n++;
}
}
return resVec;
}
}
```