首页 > 编程语言 >代码随想录算法训练营第六天 哈希法 | 242.有效的字母异位词 | 349. 两个数组的交集 | 202. 快乐数 | 1. 两数之和

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

时间:2023-01-16 21:11:41浏览次数:43  
标签:set 数组 int sum 随想录 202 哈希 unordered 两数

哈希表

哈希表适用于快速判断元素是否存在于表中,针对于哈希碰撞,有拉链法和线性探测法

拉链法

碰撞的元素被储存在链表中,拉链法需要根据数据规模选择适当的表大小,既不造成表内大量空值浪费内存,又不会产生过多碰撞使链表过长

线性探测法

线性探测法需要哈希表大小一定大于数据规模,这样在碰撞时可以向下查找到一个表中空位来解决碰撞问题。

代码内的分支

做题的时候可能会遇到使用数组,set和map三种情况。
简单来说只存键可以用set,要存键值对可以用map,数组适用于数据范围可控且较小的情况(例如只包含26个小写字母)。
set和map又可以分成是不是multi(键可重复),是不是unordered(底层使用哈希表,其他情况为有序key,底层使用红黑树)

哈希数组 lc242 有效的字母异位词

能用数组的时候用数组可以稍微提升性能,毕竟set里要做哈希映射,结构也会比数组复杂一点

class Solution {
public:
    bool isAnagram(string s, string t) {
        int hash[26]{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;
    }
};

unordered_set lc349 两个数组的交集

这道题目因为限制了数组内最大数字不超过1000,所以也可以用数组来做。注意题目要求的范围是0 <= n <= 1000,所以一共有1001个数字,声明哈希数组时大小最小是1001。

下面是使用set的解法。set还可以去重,注意不要使用multiset

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

unordered_set lc202 快乐数

本题关键在于判断循环的出现,根据题意不难发现只要某次位平方求和后的结果出现过且不为1,那么就会陷入死循环并应该返回false。这里要第一时间意识到判断一个数是否曾经出现在记录中很符合哈希法的应用场景。本题内数据范围不太可控且较大,使用unordered_set即可。

剩下的逻辑就是对快乐数计算的模拟,其中有一个小难点是把每一位(个位,十位,百位等)提取出来进行运算,看下面的代码应该就能明白如何实现了。

自己写的版本是堆在一起的,代码随想录里给的答案把一部分代码整合成了一个函数,逻辑完全一样。

放一起

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> record;
        while(n != 1){
            int result = 0;
            while(n){
                result += (n % 10) * (n % 10);
                n /= 10;
            }
            /*
            for (int num : record){
                cout<<num<<' ';
            }
            cout<<endl;
            */
            if (record.find(result) != record.end()){
                return false;
            }
            record.insert(result);
            n = result;
        }
        return true;
    }
};

代码随想录答案-函数打包

class Solution {
public:
    // 取数值各个位上的单数之和
    int getSum(int n) {
        int sum = 0;
        while (n) {
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

unordered_map lc1 两数之和

这道题很适合用map来做,因为要用值做判断并返回一个下标,如果用set可能要存有序的,时间上感觉会慢一点。

除了数据结构上的知识,这道题还需要对c++语法有一定了解。比如迭代器,泛型算法,隐式转换等。当初第一次看这道题就是差了一些c++语法的知识,导致理解不够深刻。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        std::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};
            }
            map.insert(pair<int,int>{nums[i],i});
        }
        return {};
    }
};

标签:set,数组,int,sum,随想录,202,哈希,unordered,两数
From: https://www.cnblogs.com/frozenwaxberry/p/17056284.html

相关文章

  • 2023.1.15/16 日寄
    2023.1.15日寄一言在现实断裂的地方,梦,汇成了海。——顾城昨日复习内容:组合数学「APIO2016」划艇题意\(~~~~\)\(n\)个位置,每个位置有取值区间,对于取值了的位置......
  • 2023.1.16训练日志
    AtCoderBeginnerContest285成绩报告\(AC:T1,\T2,\T3,\T4\quad1000pts\)\(rk2122,\+59\)P1280尼克的任务这道题标签是\(DP\),但是按照标签写题显得没有挑战......
  • 奇安信 2022年网络安全应急响应报告 付下载
    声明本文是学习​​2022年上半年网络安全应急响应分析报告.​​而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们应急响应事件攻ji者分析应急响应事件......
  • 代码随想录算法训练营第20天
    今日刷题4道 654.最大二叉树, 617.合并二叉树,700.二叉搜索树中的搜索,98.验证二叉搜索树● 654.最大二叉树题目链接/文章讲解:https://programmercarl.com/0654......
  • 2023.1.9周报
    2023.1.9周报本周总结本周复习了树的直径,最近公共祖先,树上差分和前缀和和tarjan求scc等内容,学习了0/1分数规划,负环,差分约束系统。大主题图论小专题树的直径,最近公共......
  • 回顾2022,展望2023
    大家好,我是练习时长5年半的java选手,回顾2022,是我的人生低谷,因为这一年我被裁了。之前工作的公司中也经历过裁员,但是当时没觉得会裁自己(事实上也没有裁我),所以没当回事......
  • 2023/1/16 20221321杨渝学习打卡
    python入门学习学习链接:https://www.bilibili.com/video/BV14r4y1k7F9/?spm_id_from=333.999.0.0&vd_source=a989a1afa6cb8b6527dd9bf059d71439字典的循环打印(解构)字典......
  • WC 2023 游记
    先写在这里,以后排版Day01.12开幕式&文艺汇演最近事比较多,浅浅地看了一下最后几分钟。当时川剧的时候演员下台和嘉宾们握手,距离比较近。握完最后一个时,突然变一张脸,那......
  • C++文学研究助手[2023-01-16]
    C++文学研究助手[2023-01-16]综合实验18文学研究助手一、实验目的(1)熟练掌握串的基本操作及应用。(2)熟练掌握串的匹配操作算法。(3)基于串的存储和操作,实现对英文......
  • C语言最短路径[迪杰斯特拉算法][2023-01-16]
    C语言最短路径[迪杰斯特拉算法][2023-01-16]算法与数据结构课程设计要求一、 题目:最短路径二、课程设计报告要求1、设计目的(1)要求熟练掌握C语言的基本知识和编程技......