day06哈希表的使用1


哈希表的查找效率O(1)

242. 有效的字母异位词

  • char型a-z到int型数组下标s[i]-‘a’。
  • for中字符串遍历结束s[i]!=‘\0’。
  • 字符串长度s.length()。
class Solution {
public:
    bool isAnagram(string s, string t) {
        //统计字符串字符出现的次数,两个字符串所有字符出现的次数一致为有效的字母异位词
       if(s.length() != t.length()) return false; 
       int statis[26] = {0};
        for(int i = 0; s[i] != '\0'; i++){
            //统计s中字符出现次数
            statis[s[i] - 'a']++;
        }
        for(int i = 0; t[i] != '\0'; i++){
            //统计t中字符出现次数
            statis[t[i] - 'a']--;
        }
        for(int i = 0; i<26; i++){
            //比较
            if(statis[i] != 0) return false;
        }
        return true;
    }
};

349 两个数组的交集

  • 使用set不用数组和map
  • set的使用:unordered_set底层实现是哈希表、无序、内容不可重复、内容不可修改,查找和增删效率O(1)
    ①初始化和赋值: unordered_set result(nums1.begin(), result.end());
    ②插入:result.insert(num);
    ③查找:result.find(num),找不到result.find(num) == result.end();效率O(1)。
class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        //标记nums1中出现的数字,遍历nums2,查字符在nums1中出现则为交集。数字范围大稀疏度高,输出结果唯一,用set。不用数组和map
        unordered_set<int> result_set;
        //保存交集
        unordered_set<int> nums1_set(nums1.begin(), nums1.end());
        //nums1中int型保存在unordered_set中
        for(int num:nums2){
            //遍历nums2中int型数据
            if(nums1_set.find(num) != nums1_set.end()){
                //在nums1的set中找到了nums2中的字符
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(),result_set.end());
        //类型转换,返回结果
    }
};

202 快乐数

  • 拆分数字得到每一位数字;
  • 哈希表unordered_set查找结果是否重复。unordered_set查找效率O(1),适用于数据非整型,数据范围不固定。
  • 问题抽象
    来自力扣官方题解
    图来自力扣官方题解
    在这里插入图片描述
class Solution {
public:
    bool isHappy(int n) {
        //平方结果重复出现不是快乐数结束
        //求解步骤:求n的每一位数字;结果1则true/查找重复false/不重复则记录
        //2^31 = 2 147 483 648 10位,平方和最大数字1 999 999 999,范围1~730,循环次数有限,sum用int
        int sum = 0;
        unordered_set<int> result_set;//保存平方结果
        while(true){
            while(n!=0){
                //n数位分离,时间复杂度logn
                int a = n%10; 
                sum+=a*a; 
                n=n/10;
            }
            if(sum == 1) return true;
            //结果1
            else if(result_set.find(sum) != result_set.end()) return false;
            //查找重复,false
            else result_set.insert(sum);
            //查找不重复,插入
            n = sum;
            sum = 0; 
        }
    }
};
class Solution {
public:
    int getNextStep(int n){
        int sum = 0;
        while(n){
            int a = n%10;
            sum += a*a;
            n = n/10;
        }
        return sum;
    }
    bool isHappy(int n) {
        int slow = n;
        int fast = getNextStep(n);
        while(fast != 1 && slow!=fast){
            slow = getNextStep(slow);//在原来的位置走1步
            fast = getNextStep(getNextStep(fast));//在原来位置走2步
        }
        return fast == 1;
        //相遇处是1或者是其他
    }
};

1 两数之和

两个数字 a+b= target。固定a,查找target - a是否存在,存在返回两个数的下标。
map插入:
map[“key”] = value;//插入相同key后者覆盖前者
map.insert(make_pair<>(“”, “”));//插入相同key前者保持不变

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //既需要保存数组元素,也需要保存数组下标,两个重要信息,用set不可
        //a+b = b+a
        unordered_map <int, int> map;
        for(int i = 0; i < nums.size(); i++){
            auto tmp = map.find(target - nums[i]);
            if(tmp != map.end()) return {tmp->second, i};
            map.insert(pair<int, int>(nums[i], i));
        }
        return {};
    }
};
  • 22
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值