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

哈希理论基础

在这里插入图片描述
哈希解决的主要问题: 快速的判断一个元素是出现在集合里。
在这里插入图片描述
在这里插入图片描述
总结: 遇到快速判断一个元素是否在集合中,就要考虑哈希法。

242.有效的字母异位词

题目链接: 242.有效的字母异位词
思路1: 利用数组作为哈希表,将字符串的每一个 字母 - ‘a’ 映射到相应的数组位置,再循环遍历另一个字符串,对应到数组位置,每次减1,最后统计一下数组每一个位置,若都是0则互为字母异位词,反之则不是。

代码如下:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int res[26] = {0};
        for(int i = 0; i < s.size(); i++){
            int x = s[i] - 'a';
            res[x]++;
        }
        for(int i = 0; i < t.size(); i++){
            int x = t[i] - 'a';
            res[x]--;
        }
        for(auto c : res){
            if(c) return false;
        }
        return true;
    }
};

思路2: 利用两个unordered_map来记录每个字符串中每个字母的数量,最后相互比较(unordered_map的比较是字典意义的比较,会逐个比较每一个元素)
代码如下:

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

349. 两个数组的交集

题目链接: 349. 两个数组的交集
思路: 利用unordered_set,首先遍历第一个数组将其中的元素放入到set中,再遍历第二个数组,遍历的过程中查看set中是否有一样的元素,有则将其放入vector 并将其在set中删除,最终得到res数组便是交集。
代码如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> set;
        vector<int> res;
        for(int i = 0; i < nums1.size(); i++) set.insert(nums1[i]);
        for(int i = 0; i < nums2.size(); i++){
            if(set.count(nums2[i])){
                res.push_back(nums2[i]);
                set.erase(nums2[i]);
            }
        }
        return res;
    }
};

202. 快乐数

题目链接: 202. 快乐数
思路1: 本题有一定的思维难度,题目规定数据大小不超过2^31 - 1,即每个位置均为9,每操作依次最大会变成810,即所有数都会变成0~810中的任意一个,且当某一个数第二次出现的时候,就会陷入一个循环,同环形链表: 环形链表在这里插入图片描述
我们的目标是看这个环中是否有1,若有1则这个环中的元素全都是1,若无1,则这个数不是快乐数。(快慢指针,slow每次操作一遍,fast每次操作两遍)
代码如下:

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

思路二: 题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

class Solution {
public:
    // 取数值各个位上的单数之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {//这可操作一定要记住
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

1. 两数之和

题目链接: 1. 两数之和
思路: 遍历数组,将每个数组元素的下标存在map里,在遍历的过程中查看map是否存在target - num[i] ,若存在将两者的下标均放入res数组中,否则就将该元素放入map中
代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        vector<int> res;
        for(int i = 0; i < nums.size(); i++){
            int n = target - nums[i];
            if(map.count(n)){
                res.push_back(i);
                res.push_back(map[n]);
            }
            map[nums[i]] = i;
        } 
        return res;      
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值