前言:明知算法做得好少,还很懒得做,吃枣药丸
1. Intersection of Two Arrays
介绍:
Given two arrays, write a function to compute their intersection.
Example:
Given nums1 = [1, 2, 2, 1], nums2 = [2, 2], return [2].
Note:
Each element in the result must be unique.
The result can be in any order.
题意:
给出两个集合(数组表示),求出两个数组的交集,交集中每个相同的元素只能出现一次
思路:
可以先对两个数组以升序的方式排序,这样我们可以对两个数组从第一个元素起一一地比较直到最后一个元素。
比如第一个数组扫到4,那么第二个数组当前元素小于4的话,就必须往后遍历,直到当前元素大于等于4。出于这种思路,同理,如果第一个数组扫到4,而第二个数组当前是6,那么应该由第一个数组往后遍历。谁当前元素更大就等谁。那么当前元素相等了呢,则这个元素就是我们要的交集的元素,加到我们的结果容器中,然后两个数组都要再往后扫一次。
有一种情况就是,如果第一个数组跟第二个数组当前元素都是4,加到结果容器后,两个往后扫,结果又都是4,又得加到结果容器中,但这不符合我们题意要求“交集中每个相同的元素只能出现一次”。所以我们还得加个判断,如果往后扫的数跟前一个数相等的话,则继续往后扫,因为这个数肯定是没意义了的。
操作:
用i遍历第一个数组nums1,则nums1当前元素为nums1[i];用j遍历第二个数组nums2,则则nums2当前元素为nums2[j]。双方一开始都停留在第一个元素,当某个数组遍历到尽头时,整个遍历过程结束,否则,如上思路,如果nums2[j] < nums1[i],或者nums2[j]跟nums2[j-1]相等时(注意,j必须大于0),j加1。对i的处理同理。
2. 代码
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
sort(nums1.begin(), nums1.end());
sort(nums2.begin(), nums2.end());
vector<int> result;
for (int i=0, j=0; i < nums1.size() && j < nums2.size(); ) {
if (nums2[j] < nums1[i] || (j > 0 ? (nums2[j] == nums2[j-1]) : false)) {
j++;
} else if (nums2[j] > nums1[i] || (i > 0 ? (nums1[i] == nums1[i-1]) : false)) {
i++;
} else if (nums2[j] == nums1[i]) {
result.push_back(nums1[i]);
i++;
j++;
}
}
return result;
}
};
3.后话
值得一提的是,另一道题目,“350. Intersection of Two Arrays II”,题意跟这一道题是一样的,不过取消了“交集中每个相同的元素只能出现一次”这个条件,那么只需要把我们代码中的那两个判断语句“(j > 0 ? (nums2[j] == nums2[j-1]) : false)”和“(i > 0 ? (nums1[i] == nums1[i-1]) : false)”删掉即可。