(写给未来遗忘的自己)
方法1:暴力求解(复杂度为O(n^2))
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
vector<int> be_mixed;
int nums1_size=nums1.size();
int nums2_size=nums2.size();
int value;
if(nums1_size>nums2_size){
for(int i=0;i<nums1_size;i++)
{
value=nums1[i];
for(int j=0;j<nums2_size;j++)
{
if(value==nums2[j])
{
be_mixed.push_back(value);
}
}
}
}else{
for(int i=0;i<nums2_size;i++)
{
value=nums2[i];
for(int j=0;j<nums1_size;j++)
{
if(value==nums1[j])
{
be_mixed.push_back(value);
}
}
}
}
sort(be_mixed.begin(),be_mixed.end());
vector<int>input;
if(be_mixed.size()==0){return be_mixed;}else{
input.push_back(be_mixed[0]);
for(int k=0;k<be_mixed.size()-1;k++){
if(be_mixed[k]!=be_mixed[k+1]){
input.push_back(be_mixed[k+1]);
}
}
}
return input;
}
};
方法2:哈希表
/*
set的三种可用的数据结构
std::set
std::multiset
std::unordered_set
std::set 和 std::multiset的底层为红黑树的实现 std::unordered_set底层实现为哈希表
*/
class Solution {
public:
vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
unordered_set<int> be_mixed;
unordered_set<int>nums1_set(nums1.begin(),nums1.end());
for(int num:nums2){
if(nums1_set.find(num)!=nums1_set.end())
{
be_mixed.insert(num);
}
}
vector<int>input(be_mixed.begin(),be_mixed.end());
return input;
}
};
知识点:
1.哈希数表的一种形式 (set)
/*
set的三种可用的数据结构
std::set
std::multiset
std::unordered_set
std::set 和 std::multiset的底层为红黑树的实现 std::unordered_set底层实现为哈希表
*/
1.1 std::set
set
是一个存储唯一元素的关联容器,它基于红黑树实现。这意味着set
中的元素会被自动排序,而且不允许有重复元素。set
提供了对数时间复杂度的插入、删除和查找操作,即O(log n)。
std::set<int> s;
s.insert(5);
s.insert(3);
// 重复插入无效
s.insert(3);
// 查找元素
auto it = s.find(3);
1.2 std::unordered_set
unordered_set
同样存储唯一元素,但它是基于哈希表实现的。unordered_set
中的元素没有固定的顺序,而且它的查找、插入和删除操作在平均情况下的时间复杂度接近于O(1)。但在最坏的情况下,时间复杂度可能退化为O(n)。
std::unordered_set<int> us;
us.insert(5);
us.insert(3);
// 重复插入无效
us.insert(3);
// 查找元素
auto it = us.find(3);
1.3 std::multiset
multiset
与set
类似,基于红黑树实现,但是multiset
允许存储重复的元素。因此,你可以在multiset
中插入多个相同的值。和set
一样,multiset
中的元素也会被自动排序,插入、删除和查找操作的时间复杂度同样是O(log n)。
std::multiset<int> ms;
ms.insert(5);
ms.insert(3);
// 可以重复插入
ms.insert(3);
// 查找元素
auto it = ms.find(3);
// 查找所有相同元素
auto range = ms.equal_range(3);
总结:
- 使用
set
和multiset
时,你需要关心元素的排序,且set
适用于唯一元素,而multiset
适用于非唯一元素。 - 使用
unordered_set
时,你更关注操作的速度,而不关心元素的顺序,且它适用于唯一元素。 - 如果需要频繁查找、插入或删除操作,并且对时间复杂度敏感,可以选择
unordered_set
;如果需要保持元素排序,可以选择set
或multiset
。 multiset
和set
在处理重复元素方面有所不同,multiset
允许重复元素,而set
不允许。
2.for循环的遍历
for (int num : nums2) {
// 这是一个范围基础的for循环,它会遍历nums2中的每一个元素。
// 每次循环,变量num都会被赋值为nums2中的下一个元素。
}
这种写法更加快速
3.迭代器
if (nums_set.find(num) != nums_set.end()) {
// 这里使用了unordered_set的一个成员函数find()。
// find()函数会在集合中搜索给定的元素(这里是num)。
// 如果元素存在,find()会返回一个指向该元素的迭代器。
// 如果元素不存在,find()会返回unordered_set::end(),这是一个特殊的迭代器,表示集合的末尾。
// 因此,如果nums_set.find(num)的结果不是nums_set.end(),
// 说明我们找到了num在nums_set中的位置,即num同时存在于nums1中。
}