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

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

时间:2023-01-17 03:00:11浏览次数:69  
标签:map set nums E5% 随想录 int 202 哈希 两数

第五天 周日 休息~【提醒补坑:链表总结还没写】

一、参考资料

哈希表理论基础

文章连接:https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html

有效的字母异位词

题目链接/文章讲解/视频讲解:https://programmercarl.com/0242.%E6%9C%89%E6%95%88%E7%9A%84%E5%AD%97%E6%AF%8D%E5%BC%82%E4%BD%8D%E8%AF%8D.html

快乐数

题目链接/文章讲解:https://programmercarl.com/0202.%E5%BF%AB%E4%B9%90%E6%95%B0.html

两数之和

题目链接/文章讲解/视频讲解:https://programmercarl.com/0001.%E4%B8%A4%E6%95%B0%E4%B9%8B%E5%92%8C.html

二、哈希表理论基础

场景需要:当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。

1.哈希表的定义

哈希表(Hash table),也称为散列表。是根据关键码的值而直接进行访问的数据结构。更为直白而言,数组就是一张哈希表。

2.解决的问题

一般用于快速判断一个元素是否在集合中。时间复杂度为O(1)。

3.基本概念理解:

1)哈希函数(哈希碰撞、拉链法、线性探测/开放寻址法)
图片来源: https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%93%88%E5%B8%8C%E8%A1%A8

哈希函数(hash function)指将哈希表中元素的关键键值映射为元素存储位置的函数。

2)哈希碰撞

如果不同的输入经哈希映射得到了同一个哈希值,就发生了"哈希碰撞"(collision)。

常用的两种解决办法:拉链法、线性探测/开放寻址法

① 拉链法

拉链法就是要选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。

图示:小李和小王在索引1的位置发生了冲突,发生冲突的元素都被存储在链表中。 这样我们就可以通过索引找到小李和小王。(数据规模是dataSize, 哈希表的大小为tableSize)

② 线性探测/开放寻址法

使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。

例如冲突的位置,放了小李,那么就向下找一个空位放置小王的信息。所以要求tableSize一定要大于dataSize ,要不然哈希表上就没有空置的位置来存放 冲突的数据了。图示:

3)常见的三种哈希结构
  • 数组

  • 集合set

  • 映射map

图片来源: https://programmercarl.com/%E5%93%88%E5%B8%8C%E8%A1%A8%E7%90%86%E8%AE%BA%E5%9F%BA%E7%A1%80.html#%E5%B8%B8%E8%A7%81%E7%9A%84%E4%B8%89%E7%A7%8D%E5%93%88%E5%B8%8C%E7%BB%93%E6%9E%84
4)参考链接

https://blog.csdn.net/weixin_44129618/article/details/122499313

https://cloud.tencent.com/developer/article/1776352

三、LeetCode242-有效的字母异位词

  1. class Solution {
  2. public:
  3. bool isAnagram(string s, string t) {
  4. // 将字符映射到数组中,大小为26,初始化均为0
  5. int record[26] = {0};
  6. // 题目中假设字符串只有小写字母,,ASCII码记为s[i] - 'a' 即可
  7. for (int i = 0; i < s.size(); i++) {
  8. record[s[i] - 'a']++;
  9. }
  10. for (int i = 0; i < t.size(); i++) {
  11. record[t[i] - 'a']--;
  12. // 提前判断一部分情况
  13. if (record[t[i] - 'a'] < 0) {
  14. return false;
  15. break;
  16. }
  17. }
  18. for (int i = 0; i < 26; i++) {
  19. if (record[i] > 0) {
  20. return false;
  21. }
  22. }
  23. return true;
  24. }
  25. };

四、LeetCode349-两个数组的交集

  1. class Solution {
  2. public:
  3. // 用unordered_set——无序、速度快
  4. vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
  5. // 定义结果集,用set可以实现去重
  6. unordered_set<int> result_set;
  7. // 对nums1数组进行去重处理
  8. unordered_set<int> nums_set(nums1.begin(), nums1.end());
  9. for (int num : nums2) {
  10. // 判断交集——nums2的元素在nums_set中出现过
  11. // 不明白为什么写成 nums_set.find(num) != nums_set.end()
  12. // 原因是nums_set.find(num)返回一个迭代器,下面找到了unordered_map返回值的说明
  13. // 返回值说明:如果给定的键存在于unordered_map中,则它向该元素返回一个迭代器,否则返回映射迭代器的末尾。
  14. if (nums_set.find(num) != nums_set.end()) {
  15. result_set.insert(num);
  16. }
  17. }
  18. // 最终的结果
  19. vector<int> result_v(result_set.begin(), result_set.end());
  20. return result_v;
  21. }
  22. };

五、LeetCode202-快乐数

  1. class Solution {
  2. public:
  3. // 殊不知,这题转化成用哈希法解决,巧妙的化解“无限循环”的问题
  4. // 快乐数是一道穿着糖衣的哈希经典题——判断某元素是否在集合里出现过
  5. //「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
  6. // 取数值各个位上的元素之和
  7. int getSum(int n) {
  8. int sum = 0;
  9. while (n) {
  10. sum += (n % 10) * (n % 10);
  11. n = n / 10;
  12. }
  13. return sum;
  14. }
  15. // 判断是否为【快乐数】
  16. bool isHappy(int n) {
  17. unordered_set<int> set;
  18. while(true) {
  19. int sum = getSum(n);
  20. if (sum == 1) {
  21. return true;
  22. }
  23. // 如果这个值在集合中出现过,返回false
  24. if (set.find(sum) != set.end()) {
  25. return false;
  26. } else {
  27. set.insert(sum);
  28. }
  29. n = sum;
  30. }
  31. }
  32. };

六、LeetCode1-两数之和

  1. class Solution {
  2. public:
  3. vector<int> twoSum(vector<int>& nums, int target) {
  4. unordered_map<int, int> map;
  5. for (int i = 0 ; i < nums.size(); i++) {
  6. // 遍历当前元素,并在map中寻找是否有匹配的key
  7. auto iter = map.find(target - nums[i]);
  8. if (iter != map.end()) {
  9. // 这个值出现过,说明iter对应的元素下标较小
  10. return {iter->second, i};
  11. }
  12. // 如果没找到匹配对,就将该元素加入map中
  13. map.insert(pair<int, int>(nums[i], i));
  14. }
  15. return {};
  16. }
  17. };

总结:

  1. 代码注释的一些感悟和理解,希望能常看常感悟;

  1. C++的语法使用又熟练了一大步;

  1. 快乐数的糖衣迷惑值得记住,学会变通的逻辑思维方式;

  1. 两数之和巧妙运用了unordered_map映射,快速又精准的解决了问题。

【记得有空填坑】

刷题加油鸭~~

标签:map,set,nums,E5%,随想录,int,202,哈希,两数
From: https://www.cnblogs.com/ucaszym/p/17056834.html

相关文章

  • Codeforces Round #844 (Div. 1 + Div. 2, based on VK Cup 2022 - Elimination Round
    比赛链接A题意设计一条线路要贴着6个墙面走,从\((a,b)\)到\((f,g)\),线路长度最短。题解知识点:模拟。分类取最短即可。时间复杂度\(O(1)\)空间复杂度\(O(1)\)......
  • 我的2022
    前言时光飞逝,光阴荏苒,2022不知不觉已结束。回想这一年里发生的事情,有辛酸不易,有困难重重,也有雨过天晴。简单总结下我的2022,无论过往如何终将逝去,愿我们在2023越来越好!一......
  • CVE-2022-46463复现文章
    本文来自博客YX'BLOGhttp://535yx.cnHarbor是为企业用户设计的容器镜像仓库开源项目,包括了权限管理(RBAC)、LDAP、审计、安全漏洞扫描、镜像验真、管理界面、自我注册......
  • 2023牛客寒假集训1
    A题WorldFinal?WorldCup!(I)(条件判断)链接:https://ac.nowcoder.com/acm/contest/46800/Ain3111111111111111111100101011010out-1106说明对于第二组......
  • 力扣每日一题2023.1.16---1813. 句子相似性 III
    一个句子是由一些单词与它们之间的单个空格组成,且句子的开头和结尾没有多余空格。比方说,"HelloWorld" ,"HELLO" ,"helloworldhelloworld" 都是句子。每个单词都只 ......
  • HTML实现除夕最美烟花,2023春节倒计时,新年不可没有烟花,最炫烟花代码分享
    ......
  • 2023牛客寒假算法基础集训营1
    2023牛客寒假算法基础集训营1https://ac.nowcoder.com/acm/contest/46800过了7题,写一半没撑住去睡觉了。官方难度预期:果然我还是很菜哇qaqA-WorldFinal?WorldCu......
  • 2023年新年第一份博客
    2023年新年第一封博客,对今年的博客做一个大概的规划:技术类:Python计算机网络软件测试理论见闻类:需要去阅读一些经典的书籍:大话存储、人月神话等其他未完待......
  • 2023.1.15
    本周总结本周主要是还是了解图论相关的一些算法,补了一下组合计数专题。大主题图论,数论小专题二分图、欧拉路径,欧拉回路组合计数题目完成情况每个专题配了一到两道......
  • 2023牛客寒假算法基础集训营1 A题
    原题链接#include<bits/stdc++.h>usingnamespacestd;intmain(){intcnt1,cnt2,n,flag=0,a,b;cin>>n;stringstring1;while(n--){cnt1=c......