两类查找问题:
1)查找有无:
- 某个元素是否存在,通常使用set(集合)
2)查找对应关系(键值对应)
- 某个元素出现了几次,map(字典)
set和map都不允许里面的键值重复。
常见操作:
- insert
- find
- erase
- change(map)
思路:把nums1放到一个set类型的record中,然后遍历nums2,若在record中找到了对应的元素就储存在另一个set类型的resultSet中。
//时间复杂度: O(nlogn)
//空间复杂度:O(n) 因为使用了额外的map来存储数据 class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { /* set<int> record; //set对于重复的元素只记录一次 for(int i=0; i<nums1.size();i++){ record.insert(nums1[i]); } */
//遍历一遍为n次,插入为logn,共O(nlogn) set<int> record(nums1.begin(), nums1.end()); set<int> resultSet; //遍历一遍并查找加修改,O(nlogn) for(int i=0;i<nums2.size();i++){ if(record.find(nums2[i]) != record.end()) //若find找到的索引不等于record.end说明存在 resultSet.insert(nums2[i]); //在record中找到了与nums2中相同的元素时,插入到resultSet } /* vector<int> resultVector; //使用容器类的迭代器 for(set<int>::iterator iter=resultSet.begin(); iter!=resultSet.end(); iter++) resultVector.push_back(&iter); result resultVector; */ //创建vector为O(n) 级别的 return vector<int>(resultSet.begin(), resultSet.end()); } };
思路:键值对应的问题:当我们记录某一元素,也要记录它对应出现的次数。使用map来记录nums1中出现的元素及其对应的次数,然后遍历nums2, 若找到相同的元素,就保存在resultVecor里,并将record减1。
class Solution { public: vector<int> intersect(vector<int>& nums1, vector<int>& nums2) { map<int, int> record; for(int i=0; i<nums1.size();i++) record[nums1[i]] ++; vector<int> resultVector; for(int i=0;i<nums2.size();i++){ if(record[nums2[i]]>0){ resultVector.push_back(nums2[i]); record[nums2[i]]--; } } return resultVector; } };
注意:int类型的map的会自动给没有赋值的元素一个初始值为0。一旦我们使用了实例中的某一键值,虽然这个键值之前不在map这个映射中,而我们只要访问一次,就为这个映射插入了这个元素,这个元素的值时默认值。
如果想要真正删除这个元素,需要调用 .erase()函数。
哈希表的缺点是失去了数据的顺序性。
故可以使用unordered_map来减少时间复杂度。
//349
//时间复杂度: O(n) //空间复杂度:O(n) 因为使用了额外的map来存储数据 class Solution { public: vector<int> intersection(vector<int>& nums1, vector<int>& nums2) { /* unordered_set<int> record; //set对于重复的元素只记录一次 for(int i=0; i<nums1.size();i++){ record.insert(nums1[i]); } */ //遍历一遍为n次,插入为O(1),共O(n) unordered_set<int> record(nums1.begin(), nums1.end()); unordered_set<int> resultSet; //遍历一遍并查找加修改,O(n) for(int i=0;i<nums2.size();i++){ if(record.find(nums2[i]) != record.end()) //若find找到的索引不等于record.end说明存在 resultSet.insert(nums2[i]); //在record中找到了与nums2中相同的元素时,插入到resultSet } /* vector<int> resultVector; //使用容器类的迭代器 for(set<int>::iterator iter=resultSet.begin(); iter!=resultSet.end(); iter++) resultVector.push_back(&iter); result resultVector; */ //创建vector为O(n) return vector<int>(resultSet.begin(), resultSet.end()); } };