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

文章目录

  • 一、242.有效的字母异位词
  • 二、349.两个数组的交集
  • 三、202.快乐数
  • 四、1.两数之和
  • 总结


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

题目链接

因为字母有26个且是连续的,本题使用哈希表的数组形式

整体思路:对字符串s的字母使用哈希表记录,对字符串t使用哈希表检查,如果哈希表最后结果全为0,则表示s和t是字母异位词。

代码如下:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int hash[26] = { 0 };//把hash表中的值初始化为0
        for (int i = 0; i < s.size(); i++) {
            hash[s[i] - 'a']++;//遍历数组s,每个字母与a相减,相减后的值为哈希表的下标,该下标对应的值+1,表示该字母出现次数+1
        }

        for (int i = 0; i < t.size(); i++) {
            hash[t[i] - 'a']--;//在上一步中,已经得到一张存有s字母出现次数的哈希表,遍历数组t,每个字母与a相减,相减后的值对应哈希表的下标,该下标对应的值减1,表示t和s有一个相同字母
        }

       for (int i= 0; i < 26; i++){//遍历哈希表,如果有不为零的,则表示s与t不全相等
           if (hash[i] != 0)
                return false;
       }
       return true;//遍历完全是零,则表示s与t是字母异位词
    }
};

二、349.两个数组的交集

题目链接

本题涉及交集,需要去重,使用unordered_set求解。

整体思路:将数组nums1保存在哈希表nums_set去重,遍历数组nums2,查看其中是否有哈希表中的数,如有则保存在结果哈希表result中

代码如下:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set;//存放结果
        unordered_set<int> nums_set(nums1.begin(), nums1.end());//把nums1去重,存在nums中
        for (int num: nums2){ //遍历nums2,看是否有nums中的数,如果有则为交集中的数
            if (nums_set.find(num) != nums_set.end()) {//如果在nums中找到num,将num存入结果中
                result_set.insert(num);
            }
        }

        //int num;//以上一段for循环等同于这样写,上面的是C++11的基于范围的for循环
        //for (int i= 0; i < nums2.size(); i++) {
        //    num = nums2[i];
        //    if (nums_set.find(num) != nums_set.end()) {
        //      result_set.insert(num);
        //    }
        //}
        
        return vector<int>(result_set.begin(), result_set.end());
    }
};

提示:力扣改了测试数据后,数组长度小于等于1000,也可以用数组的方法做。

三、202.快乐数

题目链接

本题需要使用哈希法来判断:求和的过程中sum是否重复出现。如果重复出现了就返回false,否则一直找到sum=1为止。

注意:当遇到要快速判断一个元素是否出现在集合里的时候,就要考虑哈希法了!

同时,求和的过程也是一个难点,日后需要多熟悉。

整体思路:定义一个哈希表sum_set存储每次求和的结果。每次求和后,判断和是否为1,为1则返回true。如果和不为1,在哈希表sum_set中寻找是否存在与当前和相同的数值,若有则返回false,表示有重复出现的和;否则,将当前和插入哈希表中。最后,更新要求和的值n,进行下一次循环。

代码如下:

class Solution {
public:
    int getSum (int n) {//定义一个函数求取各个位上数字的平方和
        int sum = 0;
        while (n) {//(1)(2)为取数值各个位上的单数操作,需要熟悉
            sum += (n % 10) * (n % 10);//(1)取最后一位进行平方,并求和
            n = n / 10;//(2)向前移动一位操作
        }
        return sum;
    }

    bool isHappy(int n) {
        unordered_set<int> sum_set;//定义一个哈希表用来存放和
        while(1) {
        int sum = getSum(n);//对当前n求和
        if (sum == 1) {//如果sum=1则返回true
            return true;
        }
        if (sum_set.find(sum) != sum_set.end()){//如果在sum_set中找到相同的值则返回false
            return false;
        }
        else{
            sum_set.insert(sum);//如果sum_set中没有该值,将其插入哈希表
        }
        n = sum;//更新n的值,注意是在所有操作完之后再更新
        }  
    }
};

注意: if (sum_set.find(sum) != sum_set.end())中:哈希表sum_set.end()返回的是末端的迭代器,这句话表示找sum这个数不是找到最后也找不到(有点绕),也就是sum这个值在哈希表中,记住就可以了!!

四、1.两数之和

题目链接

本题的暴力解法不赘述了,下面是使用哈希表的方法。因为设计到下标和数值,因此使用map的形式来解决。

哈希表的基础知识,以及数组、set、map的使用情况。
C++之unodered_map
STL总结

整体思路:定义一个哈希表unordered_map存放已经遍历过的数字。遍历数组,查看当前target与当前数字之差【匹配项】是否在map中,如果在则返回当前数字的下标和此时遍历的i值;否则,将该数字和其下标插入map中。

要注意的是:本题的下标为所求的值,因此map中key为数字的值,value为数字的下标。

代码如下:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> nums_map;//定义一个哈希表在存已经遍历的数字
        for (int i = 0; i < nums.size(); i++){
            auto iter = nums_map.find(target - nums[i]);//查找target与当前数字的差值是否在哈希表中
            if (iter != nums_map.end()) {//如果在就返回数字的下标
                return {iter->second, i};
            }
            else //否则,将数字的值和下标作为key和value插入map中
                nums_map.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};

总结

由于对set、map数据结构的不熟悉,今天花费了较多时间学习相关的知识。今天初步掌握了哈希表的思想,对一些函数的使用还需要更熟悉一点。

你可能感兴趣的:(哈希算法,leetcode,算法)