代码随想录算法训练营第六天| 242.有效的字母异位词 、349. 两个数组的交集 、202. 快乐数、1. 两数之和

哈希表理论基础

哈希表

哈希函数hashcode()

哈希碰撞(哈希冲突)

解决哈希冲突方法:1.拉链法(链表存同哈希值元素)2.线性探测法(放到下一个位置)

三种常见哈希结构:数组、set、map

242.有效的字母异位词

class Solution242{
public:
    /// @brief 给定两个字符串s和t判断t是否是s的字母异位词
    /// 字符串中每个出现过的字符出现的次数都相同即为字母异位词
    /// @param s 
    /// @param t 
    /// @return 
    bool isAnagram(string s,string t){
        // 哈希表专题,就直接用哈希表了
        unordered_map<char,int> res_map;
        char *sPtr=&s[0];
        char *tPtr=&t[0];
        while(*sPtr!='\0'){
            res_map[*sPtr]=0;
            sPtr++;
        }
        while(*tPtr!='\0'){
            res_map[*tPtr]=0;
            tPtr++;
        }
        sPtr=&s[0];
        tPtr=&t[0];
        while(!(*sPtr=='\0'||*tPtr=='\0')){
            res_map[*sPtr]++;
            res_map[*tPtr]--;
            sPtr++;
            tPtr++;
            if((*sPtr=='\0'&&*tPtr!='\0')||(*sPtr!='\0'&&tPtr=='\0')){
                return false;
            }
        }
        sPtr=&s[0];
        tPtr=&t[0];
        while(*sPtr!='\0'){
            if(res_map[*sPtr]!=0){
                return false;
            }
            sPtr++;
        }
        while(*tPtr!='\0'){
            if(res_map[*tPtr]!=0){
                return false;
            }
            tPtr++;
        }
        return true;
    }
};

代码思路很简单,但是写的很长,写的时候脑子也不清醒,犯了好多低级的语法错误。

就是简单地初始化map里面每个char的值为0

然后对char索引来加减

最后判断是否全为0即可。

写的好长好丑。。

看到题解焕然大悟,,又去读了遍题,,s和t仅包含小写字母!!!!26长度的数组就能解决。。。初始化也不麻烦了。。要认真读题啊!!!

然后发现自己对这几个库运用不熟练,去看了看一些教程。。

349. 两个数组的交集 

先读题(防止出现上一题的麻烦

两个数组的交集,不考虑顺序,输出结果每个元素唯一,ok可以不考虑数量,直接用undordered_set,把第一个的全部元素加进去,然后遍历2,把在集合中的添加到结果集合,最后返回结果集合即可

class Solution349{
public:
    /// @brief 给定两个数组 返回交集
    /// @param nums1 
    /// @param nums2 
    /// @return 
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> numSet(nums1.begin(),nums1.end());
        unordered_set<int> result;
        for(int i=0;i<nums2.size();i++){
            if(numSet.find(nums2[i])!=numSet.end()){
                result.insert(nums2[i]);
            }
        }
        vector<int> resultVec(result.begin(),result.end());
        return resultVec;
    }
};

比较简单,然后看了看文章,思路也差不多。

其实我看到nums的数值范围之后也想直接用数组来的。。。

202.快乐数

定义:

1.对于正整数 每次将其替换为每个位置上的数字平方和。

2.重复这个过程直到这个数变为1,也可能永远变不成1

3.如果变为1则为快乐数

没思路。。。思考这个过程和哈希的共同点?

想变成1,上一步就得到10的幂,

1和3  10,6和8   100,,没了

然后。。10个和10个3,10个6和10个8.。好像已经想偏了

看文章了,,看到无限循环这几个字,,重复出现,嗯懂了。

就循环计算,每次计算记录结果,如果结果已经在哈希表中出现过一次,那么就false,,如果得到1就true。ok,编码

class Solution202{
public:
    /// @brief 编写一个算法来判断一个数 n 是不是快乐数。
    /// 「快乐数」 定义为:
    /// 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
    /// 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
    /// 如果这个过程 结果为 1,那么这个数就是快乐数。
    /// @param n 
    /// @return n是快乐数则返回true,否则false
    bool isHappy(int n){
        unordered_set<int> hashSet;
        int res=0;
        while(n!=1){
            if(hashSet.find(n)==hashSet.end()){
                hashSet.insert(n);
            }
            else{
                return false;
            }
            while(n>0){
                res+=pow(n%10,2);
                n/=10;
            }
            n=res;
            res=0;
        }
        return true;
    }
};

有了思路就很简单了。。。。

思路一点没有,不快乐了。

1. 两数之和

简单思路是循环套循环,,但是是n方,pass

这个题放到了哈希表的专题下面一定有它的道理,嗯。

为啥哈希啊

看文章吧。。

存放遍历过的元素,,一脸懵逼

不仅需要知道是否遍历过,也需要知道对应下标,,知道这些干啥,懵

看一眼代码,,

找互补的数。

ok重新整理一下思路:题目为两数之和,找数组中的两个值和为target,我们要减少遍历的次数,就需要用一种方法记录已经见过的值,并且能够快速地在已经见过的值中找到一个值用来和当前的值互补。已经记忆过的不重复的值(但是index可能重复),而我们需要的是返回下标,就需要记录下标,map完美匹配。

ok思路整理完毕,开始编码

class Solution1{
public:
    /// @brief 两数之和,好精妙的哈希,找出数组nums中两个数的下标,这两个数的和为target
    /// @param nums 
    /// @param target 
    /// @return 返回两个数下标的数组
    vector<int> twoSum(vector<int>& nums,int target){
        unordered_map<int,int> hashMap;
        int temp=0;
        for(int i=0;i<nums.size();i++){
            temp=target-nums[i];
            auto it=hashMap.find(temp);
            if(it!=hashMap.end()){
                //说明找到了
                return {it->second,i};
            }
            hashMap[nums[i]]=i;
        }
        return {};
    }
};

哈希真的很美妙

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值