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

53 阅读2分钟

242.有效的字母异位词

题目链接:leetcode.cn/problems/va…

要点

  • 数组定义int record[26] = {0};;字符串长度size()方法;c++三目运算?:

使用哈希数组

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};
        int index = 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']--;
        }
        //看有没有异位词
        while (record[index] == 0){
            index++;
            if (index == 26) break;
        }
        return index == 26 ? true : false;
    }
};

总结

用数组作哈希的结构,读下标直接存取

349. 两个数组的交集

题目链接:leetcode.cn/problems/in…

要点

  • 使用begin(), end()迭代器初始化集合vector, set
  • for (int num : nums2)遍历nums2中的所有元素
  • unordered_set.find()方法,返回找到元素的迭代器,否则返回指向unordered_set末尾的迭代器
  • 第一个set存储nums1中的元素并去重
  • 第二个存放结果的set,只起去重的作用
  • 第一个set可以改使用数组做哈希,数组通过取下标获取数据 比 set去计算哈希值映射要快

set + set

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result; 
        unordered_set<int> nums1_set(nums1.begin(), nums1.end()); 

        for (int num : nums2) {
            if (nums1_set.find(num) != nums1_set.end()){
                result.insert(num);
            }
        }
        
        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 hash[1005] = {0};

        for (int num : nums1) {
            hash[num] = 1; //不是++,也相当于去重了
        }
        for (int num : nums2) {
            if (hash[num] == 1){
                result.insert(num);
            }
        }
        return vector<int>(result.begin(), result.end());
    }
};

总结

unordered_set用来去重,find()用哈希找元素

202. 快乐数

题目链接:leetcode.cn/problems/ha…

要点

  • 同上题思路,用unordered_set
  • 持续getSum()取下一个数,直到为1为止;或出现了循环的数字,就返回false退出

使用unordered_set去重检测是否循环了

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while (n) {
            int num = n%10;
            sum += num * num;
            n /= 10;
        }
        return sum;
    }

    bool isHappy(int n) {
        unordered_set<int> set;
        set.insert(n);

        while (1) {
            int sum = getSum(n);
            if (sum == 1) {
                return true;
            }

            if (set.find(sum) == set.end()){
                set.insert(sum);
                n = sum;
            }else {
                return false;
            }
        }
    }
};

总结

方法定义要写在main方法前,不然找不到定义

1. 两数之和

题目链接:leetcode.cn/problems/tw…

要点

  • unordered_mapkey唯一且无序,通过哈希表实现;可以通过iter->first, iter->second获取key, value
  • auto属性通常用来作为iter迭代器的属性
  • 这题map用来存已经遍历过的元素的值和下标,以便遍历后面的元素时,可以通过计算哈希迅速知道前面是否有可以与其组成 pair 的元素及其下标

使用unordered_map

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.count(target-nums[i])){
                return vector<int>{map.find(target-nums[i])->second, i};  //iter->second 获取value
            }
            map.insert(make_pair(nums[i], i));
            //map.insert(pair<int, int>(nums[i], i));
        }
        return vector<int>{};
    }
};

总结

unordered_map每对元素存一个键值对,键是唯一的,可通过find()方法返回对应迭代器