代码随想录算法训练营第6天 | 哈希表理论基础, 242.有效字母异位词 anagram, 349. 两数组交集, 202. 快乐数, 1.两数之和

哈希知识一些记录:

  • 虽然std::set、std::multiset 的底层实现是红黑树,不是哈希表,std::set、std::multiset 使用红黑树来索引和存储,不过给我们的使用方式,还是哈希法的使用方式,即key和value。所以使用这些数据结构来解决映射问题的方法,我们依然称之为哈希法。 map也是一样的道理。
  • 哈希法也是牺牲了空间换时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
  • 做面试题目时遇到需判断一个元素是否出现过的场景也应该第一时间想到哈希法

#242 anagram multiset和unordered_map都试了下,看代码随想录答案用的array,容易的快题,

注意:

1 erase(key)not value

2 map[char]+=1; 如果一开始不存在,会自动创一个,并使用该类型的默认值进行初始化,比如0

3 string 不用管 \0,遍历可用 传统i++, itr++, auto ele:str

bool isAnagram(string s, string t) {
        //multiset (repeated letter, no cnt)
        multiset setT;
        for( int i =0; i
bool isAnagram(string s, string t) {
        //unordered_map (letter: cnt)
        unordered_map mapt;
        for( int i =0; i::iterator it = mapt.begin(); it != mapt.end(); ++it) {
            cout << "Key: " << it->first << " Value: " << it->second << endl;
        }
        for( int i =0; i

#349 intersection of array

这是标准思路,找到了直接push back vec

vector intersection(vector& nums1, vector& nums2) {
        set set1;
        set set2;
        for (int i=0; i res;

        for(set::iterator it=set1.begin();it!=set1.end();it++){
                if(set2.find(*it)!=set2.end()){
                res.push_back(*it);
            }
        }
        return res;
    }
vector intersection(vector& nums1, vector& nums2) {
        set set1;
        set set2;
        for (int i=0; i res;
        
        for (auto it = set1.begin(); it != set1.end(); ) {
        if (set2.find(*it) == set2.end()) {
            it = set1.erase(it);  // 删除元素,并更新迭代器
        } else {
            ++it;  // 移动到下一个位置
        }
    }

    for (auto it = set1.begin(); it != set1.end(); it++) {
        res.push_back(*it);
    }
        return res;
        
    }

上面这是我一开始的思路:找到了不是的从nums1里删掉,最后num1统一转vec

关键易错点是 不能边itr 边 erase(itr),要做处理,因为erase了不用++了,它相当于自动++了

#202 快乐数

bool isHappy(int n) {
        //brute force
        //multiset
        set nset;
        multiset myset;
        nset.insert(n);

        while(1){
            myset.clear();
            while(n/10!=0){
                int digit=n-(n/10)*10;
                n/=10;
                myset.insert(digit); 
            }
            myset.insert(n);
        
            n=0;
            for(const auto& ele : myset) {
                n+=ele*ele;
            }
            
            if(n==1){
                return true;
            }

            if(nset.find(n)==nset.end()){
                nset.insert(n);
            }
            else{
                return false;
            }
        }

        return false;
        
    }

这题自己写的,不难,但时间复杂度不会分析,问了gpt也没看懂。代码随想录的答案好像跟我差不多,没仔细看,时间复杂度again不会分析

#1 两数之和 经典
折腾半天得有1小时,其实自己思路快对了,看了答案思路略微修改

我已经想到 1 必须用map 因为要index 2 pair(nums[i],i)是和正常相反的

vector twoSum(vector& nums, int target) {
        unordered_map mymap;
        vector res;

        for (int i=0; isecond);
                res.push_back(i);
                break;
            }
            else{
                mymap.insert(make_pair(nums[i],i));
            }
            
        }
        return res;
    }

代码随想录算法训练营第6天 | 哈希表理论基础, 242.有效字母异位词 anagram, 349. 两数组交集, 202. 快乐数, 1.两数之和_第1张图片

没想到的点是不要一次放完,要边放边找,解决(3,3)那种case

今天其他学到的:

1.标答里两句要学:set和vec的互相转化,直接用begin end itr
unordered_set nums_set(nums1.begin(), nums1.end());
return vector(result_set.begin(), result_set.end());

2.set find(*it), erase(it) 
map find(key) ,erase(key)

3 auto &, &代表是not copy,就是原来那个

然后多用c++11特性,比如 auto和 range for

 

你可能感兴趣的:(代码随想录一刷,c++,开发语言)