您的位置:首页 > 其它

[leetcode] 350. Intersection of Two Arrays II

2016-05-24 11:37 399 查看
Given two arrays, write a function to compute their intersection.

Example:

Given nums1 = 
[1, 2, 2, 1]
, nums2 = 
[2,
2]
, return 
[2, 2]
.

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 num2'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?

这道题是第349题(传送门)的后续,重复的元素也存入交集,题目难度为Easy。

先来个用Hash Table的版本,整体和第349题相似,不同的是需要统计每个元素出现的次数。具体代码:class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
unordered_map<int, int> hash;
vector<int> ret;

for(auto num:nums1) ++hash[num];
for(auto num:nums2) {
if(hash[num]) {
--hash[num];
ret.push_back(num);
}
}

return ret;
}
};

假设nums1数组大小为m,nums2数组大小为n,上面代码的时间复杂度为O(m+n),空间复杂度为O(min(m, n)),因为可以选小的数组来建Hash Table。

在处理第349题时觉得排序时间复杂度太高没有推荐排序的方法,这里题目提示已排好序,那就再来个排序的版本。具体代码:class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> ret;
int idx1 = 0, idx2 = 0;
int sz1 = nums1.size(), sz2 = nums2.size();

sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());

while(idx1 < sz1 && idx2 < sz2) {
if(nums1[idx1] == nums2[idx2]) {
ret.push_back(nums1[idx1]);
++idx1;
++idx2;
}
else if(nums1[idx1] < nums2[idx2]) {
++idx1;
}
else {
++idx2;
}
}

return ret;
}
};

如果数组已排序,最好情况时间复杂度为O(min(m, n)),最坏情况时间复杂度为O(m+n)(不含排序),比用Hash Table的方法效率要高了,空间复杂度取决于排序算法。

如果n比m大很多,可以遍历nums1然后在nums2中做二分查找,具体代码:class Solution {
public:
vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
vector<int> ret;
int idx1 = 0;
auto it2 = nums2.begin();

sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());

while(idx1 < nums1.size() && it2 != nums2.end()) {
int cnt1 = 0, cnt2 = 0;
int num = nums1[idx1];
auto it = lower_bound(it2, nums2.end(), nums1[idx1]);
it2 = it;
while(idx1 < nums1.size() && nums1[idx1] == num) {
++idx1;
++cnt1;
}
while(it2 != nums2.end() && *it2 == num) {
++it2;
++cnt2;
}
for(int i=0; i<min(cnt1, cnt2); ++i)
ret.push_back(*it);
}

return ret;
}
};这样能将时间复杂度降到O(mlogn),在n比m大很多时效率会比较高。题目中提到的最后一种情况就可以从硬盘中批量读出nums2数据,按照上述方法来找交集。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息