代码随想录 | Day07 | 哈希表:有效的字母异位词&&两个数组的交集&&快乐数&&两数之和

代码随想录 | Day07 | 哈希表:有效的字母异位词&&两个数组的交集&&快乐数

主要学习内容:
1.哈希表的使用
2.set的相关操作,find和count函数

242.有效的字母异位词

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

解法:哈希表

思路:map容器一个记录字符一个记录数量不一样直接输出false即可

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.size()!=t.size())
            return false;
        unordered_map<char,int> ps;
        unordered_map<char,int> pt;
        for(auto c:s)
            ps[c]++;
        for(auto c:t)
            pt[c]++;
        int n=s.size();
        for(auto c:s)
            if(ps[c]!=pt[c])
                return false;
        return true;
    }
    /*这样写可以少用一个哈希表
    bool isAnagram(string s, string t) {
        if(s.size()!=t.size())
            return false;
        unordered_map<char,int> ps;
        for(auto c:s)
            ps[c]++;
        for(auto c:t)
            ps[c]--;
        int n=s.size();
        for(auto c:s)
            if(ps[c]!=0)
                return false;
        return true;
    }*/
};

349.两个数组的交集

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

解法:哈希表

思路:

1.如果使用undered_map记录数字有没有出现过然后一一判断的话,会出现结果集合中重复元素的出现

比如nums1是1,2,2,1而nums2是2,2

res就会是2,2而不是2

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        unordered_map<int,int> p;
        for(auto c:nums1)
            p[c]++;
        for(auto c:nums2)
            if(p[c]!=0)
                res.push_back(c);
        return res;
    }
};

2.自认为改进了其实还是错的

把nums1和nums2对调一下就还是错的

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        vector<int> res;
        unordered_map<int,int> p;
        for(auto c:nums1)
            p[c]++;
        for(auto c:nums2)
            if(p[c]==1)
                res.push_back(c);
            else if(p[c]>1)
            {
                p[c]=0;
                res.push_back(c);
            }
        return res;
    }
};

3.正确写法是用set,set不允许重复,然后返回结果是直接用set初始化vector然后返回即可

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> r;
        unordered_set<int> s(nums1.begin(),nums1.end());
        for(int num:nums2)
            if(s.find(num)!=s.end())
                r.insert(num);
        return vector<int>(r.begin(),r.end());
    }
};

202.快乐数

202. 快乐数 - 力扣(LeetCode)

解法:哈希表

关键:要想到陷入了无限循环是有了重复的数字出现才导致了无限循环,第一次做没有想明白这一点

知道了这一点剩下的就很容易了

把所有得到的数字都加入到set中,有重复就说明无限循环然后直接false,没有重复最后肯定到1,等于1就返回true即可

class Solution {
public:
    int getnum(int n)
    {
        int res=0;
        while(n)
        {
            res+=((n%10)*(n%10));
            n/=10;
        }
        return res;
    }
    bool isHappy(int n) {
        unordered_set<int> s;
        
        while(true)
        {
            int temp=getnum(n);
            if(temp==1)
                return true;
            if(s.count(temp))
                return false;
            s.insert(temp);
            n=temp;
        }
        return false;
    }
};
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++) {
            // 遍历当前元素,并在map中寻找是否有匹配的key
            auto iter = map.find(target - nums[i]); 
            if(iter != map.end()) {
                return {iter->second, i};
            }
            // 如果没找到匹配对,就把访问过的元素和下标加入到map中
            map.insert(pair<int, int>(nums[i], i)); 
        }
        return {};
    }
};

1.两数之和

梦开始的地方

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

解法:哈希表

思路

用unordered_map来进行元素标记,first为nums[i],second为对应元素下标i,然后再哈希表中查找target-i,能找到说明就是答案,找不到就说明没有答案

错误写法:

先建立了一张哈希表,然后再遍历一遍去匹配有没有答案,问题是如果碰到重复元素,map中只会记录一个,自然而然下标也只有一个

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> s;
        int l,r;
        for(int i=0;i<nums.size();i++)
            s[nums[i]]=i;
        for(auto c:nums)
            if(s.find(target-c)!=s.end())
            {
                l=s[c];
                r=s[target-c];
            }
        return {l,r};
    }
};

正确写法:

在第一遍遍历时候就开始找,这样做,重复元素的nums[i]和i就不会进入哈希表而是直接输出成为答案,从而避免了这样的问题

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> s;
        for(int i=0;i<nums.size();i++)
        {
            auto it=s.find(target-nums[i]);
            if(it!=s.end())
                return {it->second,i};
            else
                s.insert({nums[i],i});
        }
        return { };
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值