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

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

学习文档链接: 代码随想录

一、242. 有效的字母异位词

链接: 有效的字母异位词

该题思路:

(1)使用数组:新建一个有26个字符的数组,通过遍历s增加对应的数组值,遍历t减小对应的数组值,最后遍历整个数组,如果数组值均为0,返回true,否则返回false。数组缺点:如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费!
(2)使用unordered_map(char,int),原理与上面一致,不过复杂度相对数组较高。

(1)使用数组,详细代码如下:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        //在做此类问题时候一定要先弄清楚映射关系,即索引和代表内容的关系。
        for(int i = 0;i<s.size();i++){
            record[s[i]-'a']++;
        }
        for(int i = 0;i<t.size();i++){
            record[t[i]-'a']--;
        }
        for(int i = 0;i<26;i++){
            if(record[i]!=0){
                return false;
            }
        }
        return true;

    }
};

(2)使用unordered_map(char,int),详细代码如下:

/**
*2024-5-13
* 使用unordered_map的key存储元素,value统计次数。此方法复杂度比使用数组高。
**/
class Solution {
public:
    bool isAnagram(string s, string t) {
        unordered_map<char ,int> myMap;
        for(const char &c: s){ //加&表示可以修改c,加const是因为不需要修改。与for(char c: s)相同。因此使用了引用以避免对字符串字符进行复制,这有助于提高效率。
            myMap[c] +=1;
        }
        for(const char &d: t){
            myMap[d] -=1;
        }
        for(const auto &pair:myMap){
            if(pair.second!=0){
                return false;
            }
        }
        // for(auto it = myMap.begin();it!=myMap.end();it++){
        //     if(it->second!=0){
        //         return false;
        //     }
        // }
        return true;
    }
};

二、349. 两个数组的交集

链接: 两个数组的交集
初始想法:

想到使用set容器了,但是没想到使用find()函数,只想到数值比较,导致在找到值的时候,考虑插入值到result时,不知道如何下手。所以就使用了暴力双重循环,下面将两种思路均写出来,详细代码如下:

(1)暴力遍历法
时间复杂度为o(n^2),详细代码如下:

/**
* 2024-05-13
* 暴力双层循环,时间复杂度o(n^2),想到使用set容器了,但是没想到使用find()函数,只想到数值比较,导致在找到值的时候,考虑插入值到result时,不知道如何下手。
**/
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> mySet;
        vector<int> v;
        for(const int &a:nums1){
            for(const int &b: nums2){
                if(a == b){
                    mySet.insert(b);
                }
            }
        }
        for(auto it = mySet.begin();it!=mySet.end();it++){
            v.push_back(*it);
        }
        return v;
    }
};

(2)使用set容器

使用unordered_set,同时用find()函数。需要注意的是使用数组初始化set容器时,可用 unordered_set mySet(nums1.begin(),nums1.end());不需要遍历赋值。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        
        unordered_set<int> mySet(nums1.begin(),nums1.end());
        for(const int &b : nums2){
            if(mySet.find(b)!=mySet.end()){
                result.insert(b);
            }
        }
        vector<int> res(result.begin(),result.end());
        return res;
    }
};

三、第202题. 快乐数

链接: 快乐数
初始想法:没有读懂题目的内容,不清楚如何返回false的情况,没有捕捉到无限循环这个信息。

思路:一定要看清楚题目的关键点,就是如果不是快乐数,那么一定会无限循环,那么就可以通过判断该数有没有出现过从而判断是否是快乐数。所以使用哈希set来快速查询该数的情况,使用find()函数来查询是否出现过。

/**
*2024-05-14
* 得到一个数的个、十、百、千等时,就用x%10取余,然后再用x/10取商迭代x,依次就能得到个、十、百、千等。
*/
class Solution {
public:
    int getSum(int x){
        int sum = 0;
        while(x){//x>0时执行
            sum += (x%10)*(x%10);
            x = x/10;
        }
        return sum;
    }
    bool isHappy(int n){
        unordered_set<int> mySet;
        while(n>=1){
            if(n == 1)
                return true;
            else if(mySet.find(n)!=mySet.end())
                return false;
            else{
                mySet.insert(n);
                n = getSum(n);
            }
        }
        return true;
    }
};

四、1. 两数之和

链接: 两数之和

思路:

(1)暴力循环
(2)哈希法:查询元素这种情况使用哈希法,从数组、unordered_set、unordered_map这三种中选择,由于n最大为10^4,所以不适合使用数组,数组太过浪费空间,由于题目中不仅需要元素的值,还需要元素的下标,所以不能使用unordered_set,只能使用unordered_map,key存元素值,value存元素下标。

/**
*2024-05-14
*
**/
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> myMap;
        vector<int> v;
        for(int i =0;i<nums.size();i++){
            if(myMap.find(target-nums[i])!=myMap.end()){
                auto it = myMap.find(target-nums[i]);
                v.push_back(i);
                v.push_back(it->second);
            }
            else
                myMap[nums[i]] = i;
        }
        return v;
    }
};

总结

在使用哈希法做题目时,一定要弄清楚映射关系,不然很难做正确。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值