算法学习day6

算法学习day6

  • 1. 哈希表理论基础
  • 2. 力扣242题-有效的字母异位词
    • 2.1 分析
    • 2.2 代码
  • 3. 力扣349题-两个数组的交集
    • 3.1 分析
    • 3.2 代码
  • 4. 力扣202题-快乐数
    • 4.1 分析
    • 4.2 代码
  • 5. 力扣1题-两数之和
    • 5.1 分析
    • 5.2 代码
  • 6.参考资料

1. 哈希表理论基础

1.哈希表基础.
哈希表是根据关键码的值直接访问的数据结构。
例:数组,数组下标(关键码)。通过下标直接访问数组中的元素。
一般哈希表都是用来快速判断一个元素是否出现在集合里。
2.哈希函数.
例:哈希函数,可以将学生的姓名直接映射为哈希表上的索引,通过查询索引下标可以知道同学是否在这所学校里。
算法学习day6_第1张图片
3.哈希碰撞.
算法学习day6_第2张图片
图片来源:代码随想录

2. 力扣242题-有效的字母异位词

2.1 分析

1.数组是一个简单的哈希表,题目中字符串不含有大写。定义一个大小为26的数组来统计。
2.首先将26个字母映射成数字当做数组的下标来统计数量。s[i] - ‘a’,a-z用下标索引0-25表示。同时将索引对应的元素的值加1.
3.同理统计第二字符串并将索引对应的元素减1.
4.最后循环遍历数组,如果存在有不为0的数值。说明字符串s、t,不相同(指的是内容不同)、位置无关。否则说明为有效的字母异位词。

2.2 代码

class Solution {
public:
    bool isAnagram(string s, string t) {
        int num[26] = {0};
        //将26个字母映射成数字当做数组的下标统计数量
        for(int i = 0 ; i < s.size() ; i++){
            num[s[i]-'a']++;
        }
        //统计第二个字符串,并减1
        for(int i = 0 ; i < t.size() ; i++){
            num[t[i]-'a']--;
        }
        //若为有效的字母异位词数组必全为零,若出现其他值,必为false
        for(int i = 0 ; i < 26 ; i++){
            if(num[i] !=0){
                return false;
            }
        }
        return true;
    }
};

3. 力扣349题-两个数组的交集

3.1 分析

1.std::set、std::multiset底层实现是红黑树。std::unordered_set底层实现是哈希表。使用unordered_set读写效率最高,且不需要对数据进行排序。
2.定义一个result的set哈希表,存放最后要返回的结果,因为unordered_set可以在插入元素的时候自动去重。
3.将nums1中的元素放入另外一个unordered_set nums_set中,去重。
4.遍历nums2中的元素,若发现元素在nums_set中也存在,将该元素插入到result中。
5.遍历结束将result转换回vector.

3.2 代码

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 i = 0 ; i < nums2.size() ; i++){
            //如果nums2[i]元素不存在集合nums_set中,返回迭代器nums_set.end()
            if(nums_set.find(nums2[i]) != nums_set.end()){
                //不用考虑去重操作了
                result.insert(nums2[i]);
            }
        }
        return vector<int>(result.begin(),result.end());
    }
};

4. 力扣202题-快乐数

4.1 分析

1.关键点:当重复出现就不是快乐数了。

4.2 代码

class Solution {
public:
    //求各个位置上数字的平方和
    int getSum(int n){
        int sum = 0;
        while(n){
            sum += (n%10) * (n%10);//算每一位的平方和
            n = n /10;//移动数字的位
        }
        return sum;
    }

    bool isHappy(int n) {
        //快速判断一个元素是否出现在集合里,用哈希法
        //当sum重复说明不是快乐数
        unordered_set<int> set;
        while(1){
            int sum = getSum(n);
            //如果上来直接就找到了
            if(sum == 1){
                return true;
            }
            //如果这个sum重复出现,陷入死循环,说明不是快乐数
            if( set.find(sum) != set.end()){
                return false;
            }else{
                set.insert(sum);
            }
            n = sum;//更新,用新数值,继续求平方和,检测是否快乐数
        }
    }
};

5. 力扣1题-两数之和

5.1 分析

1.当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
2.key来存放元素,value来存放下标,使用map刚刚好.
3.遍历nums数组,目标值减去当前遍历到的数组。剩余的数在map中找(利用相减可以找到满足目标值的两个数字)。若找到:直接返回,没有找到往map里面存。
算法学习day6_第3张图片
算法学习day6_第4张图片
图片来源:代码随想录

5.2 代码

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> map;
        for(int i = 0 ; i < nums.size() ; i++){
            //在map中找,目标值-元素 含有。若存在返回
            //map 中键(key)存放元素 值(valur)存放下标
            if(map.find(target - nums[i]) != map.end()){
                return {map.find(target - nums[i])->second,i};
            }
            //在map中找,目标值-元素 不含有。插入map中
            else{
                map.insert(pair<int,int>(nums[i],i));
            }
        }
        //没找到返回空
        return {};
    }
};

6.参考资料

代码随想录

你可能感兴趣的:(数据结构,c++,leetcode,哈希算法)