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

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

  • 哈希表理论基础
    • 注意:
  • Leetcode242.有效的字母异位词
  • Leetcode349. 两个数组的交集
    • 注意:
  • Leetcode202. 快乐数
  • Leetcode1. 两数之和

哈希表理论基础

文章链接:哈希表理论基础
哈希法解决的主要问题:快速判断一个元素是否在集合里
哈希法包含的结构:数组、set、multiset、unordered_set、map、multimap、unordered_map
其中最常用的就是数组、unordered_set、unordered_map
代码随想录算法训练营第六天 | 哈希表理论基础、Leetcode242.有效的字母异位词 、Leetcode349. 两个数组的交集、Leetcode202. 快乐数、Leetcode1. 两数之和_第1张图片
unordered_set底层实现为哈希表,set 和multiset 的底层实现是红黑树,红黑树是一种平衡二叉搜索树,所以key值是有序的,但key不可以修改,改动key值会导致整棵树的错乱,所以只能删除和增加。
代码随想录算法训练营第六天 | 哈希表理论基础、Leetcode242.有效的字母异位词 、Leetcode349. 两个数组的交集、Leetcode202. 快乐数、Leetcode1. 两数之和_第2张图片
unordered_map 底层实现为哈希表,map 和multimap 的底层实现是红黑树。同理,map 和multimap 的key也是有序的(这个问题也经常作为面试题,考察对语言容器底层的理解)。

注意:

  1. 遗忘了的数组初始化方法:int a[n]={0}
  2. 遗忘了unordered_set、unordered_map初始化方法,后续要专门总结一下STL容器的使用

Leetcode242.有效的字母异位词

就很简单粗暴。。。用个数组直接存对应字母出现次数,没啥可说的

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

Leetcode349. 两个数组的交集

unordered_set用的不熟练,后面总结一下。

注意:

  1. 初始化时unordered_set a(b.begin(),b.end());可以实现从vector到unordered_set的拷贝,反过来也同理,可以把unordered_set里面元素拷贝到vector中。
  2. 本质上跟vector差不多,就是不重复,还有find()函数比较好用
    下面是用set存储
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        unordered_set<int> record(nums1.begin(),nums1.end());//拷贝nums1里面的元素
        for(int i=0;i<nums2.size();i++){
            if(record.find(nums2[i])!=record.end()) result.insert(nums2[i]);
        }
        return vector<int>(result.begin(),result.end());
    }
};

用数组存储可以比set省一点内存空间

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result;
        int record[1000]={0};
        for(int i=0;i<nums1.size();i++){
            record[nums1[i]]=1;
        }
        for(int i=0;i<nums2.size();i++){
            if(record[nums2[i]]) result.insert(nums2[i]);
        }
        return vector<int>(result.begin(),result.end());
    }
};

Leetcode202. 快乐数

判断某个值在不在,并且要无重复的时候,首先考虑使用unordered_set
这道题就是利用它来判断有没有进入无限循环

class Solution {
public:
    int getsum(int n){//计算平方和
        int sum=0;
        while(n/10 != 0){
            sum += (n%10)*(n%10);
            n=n/10;
        } 
        sum+=n*n;
        return sum; 
    }
    bool isHappy(int n) {
        unordered_set<int> sums;
        int sum=getsum(n);
        while(sums.find(sum)==sums.end()){//判断在不在
            if(sum==1) return true;//在就返回true
            sums.insert(sum);
            sum=getsum(sum);
        }
        return false;
    }
};

Leetcode1. 两数之和

回忆起来unordered_map的用法:最主要的是里面塞的是对组pair(a.b)
总的来说没啥好说的,都是基础用法。

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

你可能感兴趣的:(算法,散列表,哈希算法)