代码随想录打卡Day6

今天刷的题目是关于哈希表的,之前没有学过哈希表,于是去补了一下相关知识。

242. 有效的字母异位词

在了解哈希表之前我肯定是用暴力遍历的方法,但是今天看完讲解视频以后感觉用数组作为哈希表还挺方便的,代码也很简洁,看完讲解以后自己也尝试写出来了,关键是在s中出现了n次的字母必须要在t中也出现n次,用一个数组维护各个字母在s中出现的次数,在遍历t的时候将对应字母的次数逐次减一,感觉这个很像堆栈的括号匹配。
这是我的代码。

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

349. 两个数组的交集

这道题没什么难度,用python做会更加简单,直接把两个数组转化成集合,再求两个几个的交集,返回即可。
我刷这道题的收获在于了解并熟悉了C++中unordered_set类型变量的使用方法,特别是find()子函数和向量与集合相互转换的方式。
这是我的代码。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> nums1_set(nums1.begin(), nums1.end());  //将nums1转化为集合
        unordered_set<int> result;  //两个数组的交集
        for(int i = 0; i < nums2.size(); i++){
            if(nums1_set.find(nums2[i]) != nums1_set.end())  //有共同元素
                result.insert(nums2[i]);
        }

        vector<int> result_vector(result.begin(), result.end());
        return result_vector;

    }
};

202. 快乐数

这道题目需要弄清楚一点:只要这个数是快乐数,经过有限次的各位平方求和一定能得到1;如果这个数不是快乐数,那么这个数在无限次各位平方求和时,一定会在有限个数组成的集合里反复变化,而不是变得越来越大(无限不循环),为什么呢?我刚开始也有这个疑问,但是具体证明我也证不出来,这里引用一下力扣官方题解的证明。


明确了非快乐数在不断进行平方求和的过程中一定会进入循环的性质后,只需要在循环过程中不断将平方求和得到的新数添加到集合中,如果集合中已经存在,则说明已经进入循环,直接判定为非快乐数,如果出现1,则判定为快乐数。这里我直接将平方求和封装成一个函数,提高代码复用性。这是我的代码。

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> uset;
        while(n != 1){
            n = compute_sum(n);
            if(uset.find(n) != uset.end())  //在集合里,不是快乐数
                return false;
            else   //不在集合中,向里面添加元素
                uset.insert(n);
        }
        return true;
    }
    int compute_sum(int n){
        int sum = 0;
        while(n){
            sum += (n % 10) * (n % 10);
            n /= 10;
        }
        return sum;
    }
};

1. 两数之和

没学哈希表之前我也只会用暴力法做,用哈希表来做确实会好很多。
这一题需要注意的是,我们在遍历数组的同时将遍历的值和对应下标存入map,一定是值作为键值对的键,下标作为键值对的值,因为我们在查询哈希表的时候希望快速知道指定值是否在map中,此时是判断键是否在map中,而不是看键值对的值,所以这个存储顺序不能反。其次,我们在查询某个值是否在map中时,查询的应该是target-nums[i],而不是nums[i],这里很容易弄混淆。
这是我的代码。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> umap;
        for(int i = 0; i < nums.size(); i++){
            if(umap.find(target - nums[i]) == umap.end())  //不在集合中
                umap.insert({nums[i], i});
            
            else
                return {umap[target - nums[i]], i};
        }
        return {};
    }
};

哈希表还得多学多练呀!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值