打卡六十天:第六天 第三章 哈希表part01

● 哈希表理论基础

反正有了它复杂度就能够降低
在这里插入图片描述
哈希碰撞
拉链法和线性探测法

拉链法:选择适当的哈希表的大小,这样既不会因为数组空值而浪费大量内存,也不会因为链表太长而在查找上浪费太多时间。
在这里插入图片描述
线性探测法:使用线性探测法,一定要保证tableSize大于dataSize。 我们需要依靠哈希表中的空位来解决碰撞问题。

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

在这里插入图片描述
三种哈希结构:
数组
set (集合)
map(映射)

在这里插入图片描述

● 242.有效的字母异位词

就是判断两个字符串所用字母是否相同,相同true,不相同false
一种思路是直接用sort对字符串进行排序,直接对得到的两个字符串对比就可以。

class Solution {
public:
    bool isAnagram(string s, string t) {
      sort(s.begin(),s.end());
      sort(t.begin(),t.end());
      if(s==t)
      return true;
      else
      return false;
    }
};

还有一个思路就是设置一个数组,比如说record[26]={0},然后对对于一个字符串在它字母所对应的ASCII码上进行计数,比如record[ASCII],然后这个位置上的数就能够记录这个字符串上有多少个这样的字母。对于字符串1是++,字符串2是- -,然后只需要判断整个record数组是否为零。

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

● 349. 两个数组的交集

一开始的思路就是建立一个新数组,遍历题中的两个数组后,如果两个数组出现重叠的部分,将该元素存进新数组中。不过存储之前需要对这个新数组进行循环防止出现重复的元素,比如说[1,2,2,1]和[2,2]只需要输出一个2就可以了。
在这里插入图片描述
【标准答案】

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; // 用的是set里面最下边的那个哈希表。这个哈希表是用来存放结果的,之所以用set是为了给结果集去重
        unordered_set<int> nums_set(nums1.begin(), nums1.end());//nums_set 是一个无序集合,它包含了 nums1 容器中的所有不重复的整数元素。
        for (int num : nums2) {
            // 发现nums2的元素 在nums_set里又出现过
            if (nums_set.find(num) != nums_set.end()) {
                result_set.insert(num);
            }
        }
        //这段代码是在遍历 nums2 容器中的元素,并检查每个元素是否也存在于 nums_set 无序集合中。如果某个元素在 nums_set 中存在,就将它插入到 result_set 中。

//具体的执行过程如下:
//对于 nums2 容器中的每个元素 num,进行遍历。
//使用 nums_set.find(num) 来查找 num 是否存在于 nums_set 中。如果存在,find 函数将返回一个指向该元素的迭代器;如果不存在,将返回一个指向 nums_set.end() 的迭代器。
//如果 num 存在于 nums_set 中(即 find 函数返回的迭代器不等于 nums_set.end()),则将 num 插入到 result_set 中。
//最终,result_set 将包含 nums2 中存在于 nums1 的元素,并且这些元素将按照插入的顺序存储在 result_set 中。
        return vector<int>(result_set.begin(), result_set.end());
    }
};

自己重新写了一遍,但觉还是不太熟悉,可能是对这些能够直接调用的函数不熟吧,目前就了解一个大概思路。

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())for(int num:nums2)//对于数组nums2中的每个元素,将其赋值给变量num,然后执行循环体中的代码
        {
            if(nums_set.find(num)!=num_set.end)//nums_set.end() 并不是集合中的元素,而是用于标识集合的结束位置的特殊迭代器值。在使用无序集合进行迭代时,通常会使用循环来遍历集合中的元素,而结束迭代器则用于判断循环是否达到了集合的末尾。
            {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(),result_set.end());
 
    }
};

● 202. 快乐数

原理懂了还不是很会用

● 1. 两数之和

之前做过,但是也忘了,过两天再补吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值