Bootstrap

代码随想录刷题day06

哈希表

常见的三种哈希结构:

1.数组(常见于对字符串的判断,将26个字母存储在数组中,对数组对应位置的值进行处理)

注意事项:1.如果题目给定的数据限制很大,则不能使用数组

2.集合  unordered_set,当要求查找重复元素或者条件要求的数据限制很大的时候使用

3.映射 unordered_map,当需要考虑元素的值和索引时,考虑使用hash map,通过键值对找到需要的元素key:数据元素,value:索引下标

242.有效的字母异位词 - 力扣(LeetCode)

思路由于本题的数据限制较小,因此可以考虑在哈希性质下用数组做,先将26个字母存储在数组中,然后将字符串s的所有字符存储到数组中,对应数组下标为0的地方存储'a',25的地方存储'z',然后将字符串t的字符对应相减,最后判断是否数组的所有元素和为0

代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int record[26] = {0};//定义一个包含所有字母的数组,且每个单词出现的次数就是数组对应位置的数字
        int nums = 0;
        for(int i = 0;i < s.size();i++)
        {
            record[s[i] - 'a']++;//将s字符串出现的字母,在数组对应位置+1
        }
        for(int i = 0;i < t.size();i++)
        {
            record[t[i] - 'a']--;//将t字符串出现的字母,在数组对应位置-1
        }

        for(int i = 0;i < 26;i++)
        {
            nums += record[i];//判断是否此时数组中的所有元素之和是否为0,不为0则不是异位字符串
            if(nums != 0) return false;
        }
        return true;
    }
};

349.两个数组的交集 - 力扣(LeetCode)

思路:

unordered_set:

解决类似的重复元素,都可以使用无序集合去重元素

数组:

当题目给定的数据限制不大时,使用数组的效率更高,

代码:

无序集合:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
            unordered_set<int> result;
            unordered_set<int> nums_set(nums1.begin(),nums1.end());
            for(int num : nums2)
            {
                if(nums_set.find(num) != nums_set.end())//如果nums_set中没找到nums的元素,就返回end,如果不等说明存在元素num
                {
                    result.insert(num);
                } 
            }
            return vector<int>(result.begin(),result.end());

    }
};

数组:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
            int hash[1001] = {0};//定义一个数组储存可能存在的所有出现的数字
            unordered_set<int> arr;
            for(int num : nums1)//便利nums1的所有数字
            {
                hash[num] = 1;//给对应的数字赋值
            }
            for(int num : nums2)
            {
                if(hash[num] == 1)//只要该数字在nums2也出现,就存储在无序集合
                arr.insert(num);
            }
            return vector<int>(arr.begin(),arr.end());
    }
};

202.快乐数 - 力扣(LeetCode)

思路:

1.首先定义求和函数get_sum,当n/10<1,即n成为个位数时,跳出循环

2.调用求和函数,并且用无序列表储存所有出现的和,直到最后出现和为1的时候返回true,或者出现过相同的元素,返回false

3.需要考虑可能出现死循环的情况,用unordered_set,判断当前的sum有没有出现过,如果find函数找到了,则立马返回false

代码:

class Solution {
public:

    int get_nums(int n){
        int sum = 0;
        while(n)
        {
            sum += (n % 10) * (n % 10);
            n = n / 10;
        }
        return sum;
    }

    bool isHappy(int n) {
        unordered_set<int> set;
        int s;
        while(1)
        {
            s = get_nums(n);
            if(s == 1) return true;
            if(set.find(s) != set.end()) return false;
            else set.insert(s);
            n = s;
        }
    }
};

1.两数之和 - 力扣(LeetCode)

思路:

  • 为什么会想到用哈希表

当面临需要查找元素是否出现或者与集合有关的时候,需要考虑哈希表

  • 哈希表为什么用map

本题需要返回数据元素和下标,map可以存储键值对

  • 本题map是用来存什么的

用来存储遍历过后的键值对,由元素值和下标组成

  • map中的key和value用来存什么的

key存储数组的元素,value存储该元素的下标

代码:

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 ira = map.find(target - nums[i]);
            if(ira != map.end()) return {ira->second,i};//ira->first是map的key值,ira->second是map的value值
            map.insert(pair<int,int>(nums[i],i));
        }
        return {};

    }
};

;