查找表set和map 349, 350

两类查找问题:

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());
    }
};

 

posted @ 2018-12-22 14:56  爱学英语的程序媛  阅读(195)  评论(0编辑  收藏  举报