Day6|哈希表

242 有效的字母异位词

思路就是先比较两个长度,长度不一样肯定false
两个哈希表,每个string按照字母分别入表。
再遍历字符串s的每个字母,查询该字母在t表中出现次数是否与s表中出现次数相同。
很简单 一次AC
上代码:

class Solution {
public:
    bool isAnagram(string s, string t) {
        int s_len=s.size();
        int t_len=t.size();
        if(s_len!=t_len) return false;
        unordered_map<char,int> smap;
        unordered_map<char,int> tmap;
        for(int i=0;i<s_len;++i){
            if(smap.count(s[i])==0){
                smap.insert({s[i],1});
            }
            else{
                auto it=smap.find(s[i]);
                ++(it->second);
            }
            if(tmap.count(t[i])==0){
                tmap.insert({t[i],1});
            }
            else{
                auto it=tmap.find(t[i]);
                ++(it->second);
            }
        }
        for(int i=0;i<s_len;++i){
            if(tmap.count(s[i])==0) return false;
            else if((tmap.find(s[i])->second)!=(smap.find(s[i])->second)) return false;
        }
        return true;
    }
};

349. 两个数组的交集

先上代码,哈希表很容易就能做,思路不多赘述

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> result;
        int n1=nums1.size();
        int n2=nums2.size();
        unordered_set<int> mySet;
        for(int i=0;i<n1;++i){
            if(mySet.count(nums1[i])==0){
                mySet.insert(nums1[i]);
            }
        }
        for(int i=0;i<n2;++i){
            if(mySet.count(nums2[i])!=0){
                result.push_back(nums2[i]);
                mySet.erase(nums2[i]);
            }
        }
        return result;
    }
};

由这道题小小地发现了一件事
就是现在的刷题主题是哈希表
所以我在解题的时候很容易就往哈希表上想,然后只用哈希表来做,做出来就完事了。
这道题我看了眼力扣的题解,发现题解给了两种其他方法(虽然时间复杂度都不如哈希表)
但是也可以提供一些其他的思路?尤其是想要减小空间复杂度的情况下。只用哈希表做完相当于把自己的思路限制住了。
(题解给的另一种算法感觉也很好,排序+双指针,指针指向相同就取值,时间复杂度是O(mlogm+nlogn))暴力法太笨了,就不提了。

202 快乐数

一开始不知道哪里可以用到哈希表,注意力全都在如何把数的每位取下来和如何构建一个循环当sum为1的时候返回true
但是看到题中说可能会有无限循环的情况,一下子不知道怎么判断这种情况
看了一下题解,把每次sum存入哈希表,循环中如果出现相同的sum证明进入了无限循环。
一切清楚了(把数的每位取下来稍微有点绕,我是另外写了一个函数然后从个位开始取,取完就减掉再除以10,直到为0)
上代码,

class Solution {
public:
    bool isHappy(int n) {
        unordered_set<int> mySet;
        mySet.insert(n);
        if(n==1) return true;
        
        int result=n;
        while(result!=1){
            result=getSum(result);
            if(mySet.count(result)!=0) return false;
            else mySet.insert(result);
        }
        return true;
    }
    int getSum(int n){
        int s=n;
        long int i=1;//这里不加long会报错
        vector<int> each;
        if(n<10) return n*n;//进入以下的n可以保证大于10
        while(n/i>0){//=0的时候,说明i的位数已经超过n了
            each.push_back(s%10);
            s-=(s%10);
            s=s/10;
            i=i*10;
        }
        int size=each.size();
        int sum=0;
        for(int i=0;i<size;++i){
            sum+=each[i]*each[i];
        }
        return sum;
    }

};

报错如下:
报错的测试用例
int的长度溢出了,改成long int就可以直接AC了

1 两数之和

有人相爱,有人夜里看海,有人力扣第一题都做不出来

写个一开始的错误版本(这个错误版本也是稍微想了一下才写出来,不是一下子就写出来了,还是忘了上次是怎么写的了)

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> myMap;
        //sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n;++i){
            myMap.insert({nums[i],i});
        }
        vector<int> result;
        for(int i=0;i<n;++i){
            if(myMap.count(target-nums[i])!=0 ){
                
                result.push_back(i);
                
                auto it= myMap.find(target-nums[i]);
                result.push_back(it->second);
                break;
            }
        }
        return result;
    }
};

报错用例:
错误用例
想了一下发现确实,第一次把数组里所有数一股脑存到哈希表里,然后再次遍历并且对照着找哈希表里有无满足target减当前数的元素,这种情况有可能直接找到自己,然后就返回两个相同位置的元素了。

两次遍历,时间消耗也大,还可能返回相同值,怎么解决呢。

看题解去了,发现可以在第一次遍历的时候,就把数一边存入哈希表一边查询是否有满足条件的整数对,在存入表之前先查询表中有无满足条件的元素,这样很好地避免了找到自身。遂改。
上代码:

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> myMap;
        vector<int> result;
        int n=nums.size();
        for(int i=0;i<n;++i){
            if(myMap.count(target-nums[i])!=0){
                result.push_back(i);
                auto it=myMap.find(target-nums[i]);
                result.push_back(it->second);
                break;
            }
            else{
                myMap.insert({nums[i],i});
            }
        }
        
        return result;
    }
};

时间复杂度O(N),空间复杂度O(N)

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值