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

242 有效的字母异位词

题目链接:有效的字母异位词
题目描述:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

解题思想:根据题目给出的注意,很容易知道,我们只需要比对s和t中的每次字符出现的次数,如果出现的字符及其相关的次数相同,就返回为true。
因此,解题方法为:只需要将s中的每个字母出现的次数存入哈希表dict中,再遍历t中的字母,将dict中的次数减去,若最后每个字母的出现次数等于0,即表明最后是字母异位词。

法一:

class Solution {
public:
    bool isAnagram(string s, string t) {
        unordered_map<char,int>dict;
        for(char c:s)
        {
            dict[c]++;
        }
        for(char c:t)
        {
            dict[c]--;
        }
        for(auto iter=dict.begin();iter!=dict.end();iter++)
        {
            if(iter->second!=0)
                return false;
        }
        return true;
      
    }
};

这里采用的是哈希表。

注意哈希表的使用方法:

1.哈希表的构造:

unordered_map<int,int>dict;

2.哈希表的插入:

dict.emplace(1,2);
dict.insert(pair<int,int>(1,2));
dict[1]=2;
  1. 哈希表的遍历:
for(auto iter=dict.begin();iter!=dict.end();iter++)
{
	cout<<iter->first<<iter->second;
}

以上是哈希表的简单使用方法。
在本题中,可以简单的使用数组代替哈希表。(换句话说,数组就其实是哈希表,哈希表的key值其实就是数组中的索引下标i,哈希表中的value就是数组的值)

法二:使用数组代替哈希表

class Solution {
public:
    bool isAnagram(string s, string t) {
        int dict[26]={0};//作为字典,存的是s
        for(char c: s)
        {
            dict[c-'a']++;//将s每个字母存入dict里面
        }
        for(char c:t)
        {
            dict[c-'a']--;
        }
        for(int i=0;i<26;i++)
        {
            if(dict[i]!=0)
                return false;
        }
        return true;
    }
};

349、两个数组的交集

题目链接:两个数组的交集
题目描述:给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

解题思路:返回两个交集,直观的想法,我们只需要将第一个数组去重后的结果存放,第二个数组也进行相关去重后与之进行比对即可。
由于此题,我们不需要记住数组中的数字出现的次数。因此,我们采用set即可。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int>result;
        if(nums1.size()==0&&nums2.size()==0)    return result;
        unordered_set<int>set1;//存入nums1
        for(int i:nums1)
        {
            set1.emplace(i);//将num1中的每个字母都存入set1中,同时由于set是不允许遍历的,也可以去除重复的值。
        }
        for(int i:nums2)
        {
            if(set1.count(i))
            {
                result.push_back(i);
                set1.erase(i);//将i从set中删除,也可以去除重复的值。
            }
        }
        return result;
    }
};

此代码存在的问题还是set的使用不多,使用出现了较为复杂的做法,因此,可以进行相关的改进。

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

202.快乐数

题目链接:快乐数
题目描述:
编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

题目解法:
该题同样采用的是哈希表中set的用法。
需要注意的1. 需要学会如何计算每个位置上的数字的平方和。即需要弄清楚取余%和取整 / 两个符号的用法。
2. 需要注意的是如何跳出这个循环,在本题中,如果得到的平方和,在set中已经存在过了,说明该数字必定不是快乐数,将会永远陷入无限循环中。得到了这个结论,那整体的算法便很容易知道,即,只需要将每次得到的平方和存入set中,并判断是否为1,是1则将跳出循环,若存在,则返回false,跳出,若不存在,将其加入set即可。

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int>set;
        while(1)
        {
            int sum=getSum(n);
            if(sum==1)  return true;
            if(set.find(sum)!=set.end())    return false;
            else{
                set.insert(sum);
            }
            n=sum;
        }
        return false;
    }
    int getSum(int n)
    {
        int sum=0;
        while(n)
        {
            sum+=(n%10)*(n%10);
            n=n/10;
        }
        return sum;
    }
};

1. 两数之和

题目链接:噩梦开始的地方
题目描述:
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

解题思想:

  1. 暴力解法,是否循环遍历,将其每两个数字的和存入map中,并且存入相关的下标值。
  2. 采用map的方法,循环一次即可。通过遍历数组,找map中找到target-nums[i]值,如果找到,则表明在map中该数字已经遍历过了,我们只需要返回该下标和已经存在map中的下标即可。

注意事项:我们需要十分熟悉,在该题中,map是用来干啥的。
map是用来存放已经遍历过的数字及其下标的,当我们遍历新的数字是,我们便需要知道是否已经遍历过了target与该数字的差的值。因此,map便于这个用途。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int>map;
        for(int i=0;i<nums.size();i++)
        {
            auto iter=map.find(target-nums[i]);//找到相应的值
            if(iter!=map.end())
            {
                return {iter->second,i};//表示已经找到了,返回相应的值,其中iter->second表示已经找到的值的下标,而i表示当前的下标
            }
            else{
                map.insert(pair<int,int>(nums[i],i));//未找到,将该数字及其下标存入map中。
            }
        }
        return {};
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值