[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 =
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数据,按照上述方法来找交集。
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数据,按照上述方法来找交集。
相关文章推荐
- 在命令行用 sort 进行排序
- Linux Shell - 如何使用sort与uniq命令删除重复的文本行
- Redis sort 排序命令详解
- 批处理命令教学之字符串排序(sort)
- mysql Sort aborted: Out of sort memory, consider increasing server sort buffer size的解决方法
- C++ 关于STL中sort()对struct排序的方法
- C#中Arraylist的sort函数用法实例分析
- Js中sort()方法的用法
- js采用concat和sort将N个数组拼接起来的方法
- 如何写JS数组sort的比较函数
- javascript中sort()的用法实例分析
- 详解Matlab中 sort 函数用法
- js模拟实现Array的sort方法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- js表数据排序 sort table data
- javascript 数组排序函数sort和reverse使用介绍
- JavaScript Table排序 2.0 (更新)
- js中数组(Array)的排序(sort)注意事项说明
- Javascript数组的排序 sort()方法和reverse()方法
- Java数据结构及算法实例:插入排序 Insertion Sort