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

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

讲解文章,参考代码随想录:https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html#%E7%AE%97%E6%B3%95%E5%85%AC%E5%BC%80%E8%AF%BE
y总视频讲解:https://www.acwing.com/activity

242.有效的字母异位词

先看代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        unordered_map<char,int> a,b;
        for(auto c:s) a[c]++;
        for(auto c:t) b[c]++;
        return a == b;
    }
};

这道题目就是对map的考察,对于一个字符串并且和出现次数关联起来的,基本会用map。知道使用map,这道题目就会很简单,就是对两个字符串分别统计计数,然后比较,这里的容器是支持比较运算符的。

349. 两个数组的交集

先看代码:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> S;
        for(auto n:nums1) S.insert(n);
        vector<int> res;
        for(auto x:nums2)
        {
            if(S.count(x))
            {
                res.push_back(x);
                S.erase(x);
            }
        }
        return res;
    }
};

首先题目里交代了,输出唯一,当输入不唯一,但是要求输出唯一,这个时候就很容易想到使用set,因为set的特性就是保证集合中没有重复的数值。
由于返回值是vector,所以输出不能是set,可以把输入变成set。
这道题的思路就是遍历其中一个数组,然后查看另一个数组里面有没有类似的,有的话就加进答案数组,并且要在set里面删除该值。
为什么找到了,加进答案数组还要删除这个值?不删除可以吗?
回答:不删除不可以,因为比如去查找的数组里面有两个“2”,第一次发现了,如果不删除set里面的“2”,第二次再次发现“2”的时候还会将2加进答案数组,这样输出就变成不唯一了。

202. 快乐数

先看使用哈希的代码:

class Solution {
public:
    int get(int x)
    {
        int res = 0;
        while(x)
        {
            res += (x % 10) * (x % 10);
            x /= 10;
        }
        return res;
    }

    bool isHappy(int n) {
        unordered_set<int> S;
        while(1)
        {
            int sum = get(n);
            if(sum == 1) return true;
            if(S.find(sum) != S.end()) return false;  //这里S.find()是查找指定的值,如果找到返回该元素迭代器,没找到就指向容器的结束位置
            else S.insert(sum);
            n = sum;
        }

    }
};

双指针代码:

class Solution {
public:
    int get(int x)
    {
        int res = 0;
        while(x)
        {
            res += (x % 10) * (x % 10);
            x /= 10;
        }
        return res;
    }
    bool isHappy(int n) {
        int fast = get(n),slow = n;
        while(fast != slow)
        {
            fast = get(get(fast));
            slow = get(slow);
        }
        return fast == 1;
    }
    
};

这道题目比较有意思,首先是使用hash的,这个的思路是表明了的,每次算出sum,先看是否为一,如果不是,就找set里面还有没有存储这个sum,没有的话加进去,有的话说明出现先循环了,且循环中没有1,那就返回fasle
会不会有朋友说如果set里面加不怎么办?
根据题目中n的范围,我们可以假设n为一个9999999999的数,那么最后的sum的值是9910 = 810,也就是说,我n怎么变也就在这810中情况中,当我set的里面最坏加到811个数的时候就有重复的了,抽屉原理
然后继续,这样的话我们就知道n一直这么算下去有下面情况:

  1. 出现了循环,但是循环里没有1;
  2. 出现了循环,循环里有1;
  3. 就只有1,本身,1是自成环。
    所以还记得前面环形链表||的题目吗?双指针,fast和slow,这里比那个简单,就看fast和slow相遇的时候有没有1,就可以了。

1. 两数之和

暴力代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        for(int i = 0;i < nums.size();i++)
        {
            int res = target - nums[i];
            for(int j = 0;j < nums.size();j++)
            {
                if(j != i && res == nums[j])
                    return {i,j};
            }
        }
    return {};
    }
};

使用map:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> heap;
        for(int i = 0;i < nums.size();i++)
        {
            int res = target - nums[i];
            if(heap.count(res)) return {heap[res],i};
            heap[nums[i]] = i;
        }
        return {};
    }
};

这道题目就是用target减去一个数,然后在另一个数组里面找,暴力也可以。

总结
今天回顾了哈希,也学会了一些模板的方法,比find(),end(),count(),count()就是返回这个值在容器中个数,个数为0,说明不再容器中。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值