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

@代码随想录算法训练营第6天(第5天周日休息) | LeetCode454 四数相加||,383 赎金信,15 三数之和,18 四数之和

242 有效的字母异位词

题目链接: https://leetcode.cn/problems/valid-anagram/description/
视频链接:
https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无

涉及两个字符串,可能要使用双指针法?哈希表不太熟悉,看视频吧。

代码随想录解法思路

创建一个26位的数组充当哈希表,第一遍遍历字符串s,将出现的字母的次数存储到对应的hash数组的位置上,然后遍历第二个字符串对数组做减法操作,如果最后hash数组里都是0,那就是有效的字母异位词。

c++代码具体实现注意事项

具体实现中需要注意hash数组的初始化必须为0.
然后存储到对应位置可以直接用字母减法,因为程序会自动用ascii码做减法。
其他的没啥,很简单的一道题,感觉没有涉及到哈希表的本质,只是对数组的灵活应用。

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

学习时长

20分钟

349 两个数组的交集

视频链接:
https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无

感觉跟上一道题一样,创建一个长度1000的数组,然后同时遍历两个数组,用长度最小的数组作为界限,然后如果value相同就在hash表里加1.

代码随想录解法思路

看完后发现自己对题目理解有些偏差。这里的相交只需要数组里有相同的value就算相交,不需要位置也对应上。所以如果用数组做的话需要考虑数组里的value是否有finite的,不然如果非常大的话用数组需要创建一个很大的空间,可能是稀疏的空间,非常不划算。所以介绍了用unordered_set的方法,这个数据结构非常方便,可以自动去重,并且可以直接用数组初始化。

c++代码具体实现注意事项

注意使用unordered_set的语法,定义初始化的时候其实跟vector比较像,可以直接用数组初始化,然后find函数在没找到的情况下返回unordered_set::end。具体的可以参考下面的代码。

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

学习时长

27分钟

202 快乐数

视频链接:
https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无

难点在于如何判断是否会为1,也就是说必须要变成1,100,1000,10000,也就是10的n次方才行,也就是0到9是个数字的平方,分别为0 1 4 9 16 25 36 49 64 81这几个数的各种排列组合的加和。具体的看视频吧,看看怎么用到hash表的。

代码随想录解法思路

非常巧妙的考察了对题目的理解,什么时候return false,显然是在sum重复出现的情况下,所以没有必要对题目进行上述的愚蠢的数学分析,直接简单粗暴的用unordered_set去判断是否存在重复的sum即可。

c++代码具体实现注意事项

注意一下怎么取某个数的单位即可,其他的还是set哈希表的基本操作。

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

学习时长

27分钟

1 两数之和

视频链接:
https://programmercarl.com/0024.%E4%B8%A4%E4%B8%A4%E4%BA%A4%E6%8D%A2%E9%93%BE%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9.html

第一遍读题思考(五分钟内,如果没有思路就写暴力解法思路,暴力解法思路也不清晰就写无

想到会用hash表,应该是用哈希表查找的键值存储value,然后用另一个哈希表中的value存储数组中对应的下标。

代码随想录解法思路

主要学习了map的操作手法,map是查找一个key在不在表里。然后只需要遍历数组,遍历到一个数先去哈希表里查,查到了就返回下标得到两数之和,没查到就把这个数存进去。

c++代码具体实现注意事项

注意一下map的插入和取值以及找值的操作即可。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::unordered_map<int, int> hash;
        for(int i=0;i<nums.size();i++){
            auto iter = hash.find(target-nums[i]);
            if(iter!=hash.end()){
                return {iter->second, i};
            }
            else{
                hash.insert(pair(nums[i],i));
            }
        }
        return {};
    }
};

学习时长

8分钟

你可能感兴趣的:(代码随想录算法训练营第十期,算法,哈希算法,leetcode)