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

目录

 前言

LeetCode242.有效的字母异位词

LeetCode349.两个数组的交集

LeetCode202.快乐数

LeetCode1.两数之和

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

题目链接:有效的字母异位词

数组哈希法:

代码思路:

二、LeetCode349.两个数组的交集

题目链接:两个数组的交集

数组哈希法:

数组哈希表法代码思路:

unordered_set哈希表法:

unordered_set哈希法代码思路:

三、LeetCode202.快乐数

题目链接:快乐数

unordered_set哈希表法:

代码思路:

四、LeetCode1.两数之和

题目链接:两数之和

unordered_map哈希表法:

代码思路:


 前言

哈希表基础理论

文章讲解

LeetCode242.有效的字母异位词

文章讲解

视频讲解

LeetCode349.两个数组的交集

文章讲解

视频讲解

LeetCode202.快乐数

文章讲解

LeetCode1.两数之和

文章讲解

视频讲解


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

题目链接:有效的字母异位词

数组哈希法:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int strHash[26] = {0};

        for(int i = 0; i < s.size(); i++)
        {
            strHash[s[i] - 'a']++;
        }
        for(int i = 0; i < t.size(); i++)
        {
            strHash[t[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++)
        {
            if(strHash[i] != 0)
                return false;
        }

        return true;
    }
};

代码思路:

由于单词都是由26个英文字母组成,所以采用26个元素的数组可以统计所有单词的字母数量,并且通过str[i] - 'a'可以得到0-25的哈希值。统计完第一个单词的所有字母后,再统计第二个单词与第一个单词的所有字母的数量差值,如果所有字母的数量差值都为0,则两个单词的字母及数量完全一致,返回true,否则返回false。

二、LeetCode349.两个数组的交集

题目链接:两个数组的交集

数组哈希法:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        int numHash[1001] = {0};
        unordered_set<int> result_set;
        for(vector<int>::iterator it = nums1.begin(); it != nums1.end(); it++)
        {
            numHash[*it] = 1;
        }
        for(vector<int>::iterator it = nums2.begin(); it != nums2.end(); it++)
        {
            if(numHash[*it])
            {
                result_set.insert(*it);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

数组哈希表法代码思路:

题目设置了数组元素的范围是[0, 1000],所以我们可以用一个长度为1001的数组来记录出现过数字。因为集合set有天然的去重功能,且unordered_set的底层实现是哈希表,所以查找和插入的时间复杂度都是O(1) 

unordered_set哈希表法:

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

unordered_set哈希法代码思路:

由于unordered_set底层实现是哈希表,所以查找和增删的效率都是O(1),我们可以不使用数组而改用unordered_set来记录出现过的数字,不过要注意的是相比与数组,使用unordered_set的效率会更低,因为无论是查找还是增删都会比数组额外多出一个哈希值的计算。

三、LeetCode202.快乐数

题目链接:快乐数

unordered_set哈希表法:

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

代码思路:

此题使用unordered_set保存每次平方和的结果,一旦重复出现了某个结果,就说明这个数会一直循环出现,不满足快乐数的要求。

四、LeetCode1.两数之和

题目链接:两数之和

unordered_map哈希表法:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> recordMap;
        vector<int> retVec(2);
        for(int i = 0; i < nums.size(); i++)
        {
            unordered_map<int, int>::iterator it = recordMap.find(target - nums[i]);
            if(it != recordMap.end())
            {
                retVec[0] = it->second;
                retVec[1] = i;
                return retVec;
            }
            //operator[]写法如果key值存在则修改value值,如果key不存在,则添加key和value
            recordMap[nums[i]] = i;
            //insert写法如果map中已经存在key了,则会直接忽略该插入操作
            // recordMap.insert(pair<int, int>(nums[i], i));
        }
        return retVec;
    }
};

代码思路:

设置ordered_map保存的key和value分别时遍历过的nuns中的元素值以及对应元素值的下标。当我们遍历到某个值的时候,可以通过查找键值(target - nums[i])是否存在,如果存在就表示已遍历的元素中存在一个数,这个数跟当前的nums[i]相加可以等于target。


总结:

当题目有需要记录遍历的元素或者记录某些计算结果时,可以首先考虑哈希表的使用,常用的哈希表数据结构有三种:数组,unordered_set,unordered_map。其中数组适合使用再给定范围内的数据记录,unordered_set适合未给定范围的数据记录,且set本身自带去重功能。unordered_map的用法非常类似与数组,可以看成是数据更高级的使用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值