两个数组的交集 II
https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/x2y0c2/
https://leetcode-cn.com/problems/intersection-of-two-arrays-ii/
双指针
将数组排序后,使用双指针,值相同则加入并集,否则向后移动值比较小的那个指针,直到其中一方越界。
时间复杂度:排序为O(nlogn + mlogm)
,双指针移动为O(n + m)
,加起来就是O(nlogn + mlogm)
空间复杂度:由于vector
的大小是动态改变的,复杂度为O(1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { sort(nums1.begin(), nums1.end()); sort(nums2.begin(), nums2.end());
vector<int> intersection;
int n1 = 0, n2 = 0;
while ( n1 != nums1.size() && n2 != nums2.size() ) { if (nums1[n1] == nums2[n2]) { intersection.push_back(nums1[n1]); ++n1; ++n2; } else if (nums1[n1] > nums2[n2]) { ++n2; } else { ++n1; } }
return intersection; }
|
哈希表
使用哈希表来记录数字以及出现的次数。
- 遍历较短的数组,依次将数字插入哈希表。
- 遍历较长的数组,查询哈希表中是否已有该元素。如果有,就将它加入并集中,并将哈希表中的计数减一;如果没有则无需采取任何操作。
时间复杂度:遍历两个数组所用的时间O(m + n)
,哈希表的插入和查询平均都是O(1)
。
空间复杂度:创建了大小为较短数组长度的哈希表,因此是O(min(m, n))
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { if (nums1.size() < nums2.size()) return intersect(nums2, nums1);
unordered_map<int, int> m; vector<int> intersection;
for (int x: nums1) { ++m[x]; }
for (int x: nums2) { if (m.find(x) != m.end() && (m.find(x) -> second) > 0) { --m[x]; intersection.push_back(x); } }
return intersection; }
|
实现时,可以不用find(x)
来查找,直接利用count(x)
来判断表中是否存该数字,计数减一后判断计数值是不是变成0了,是的话就从表中删去此元素。