代码随想录-哈希

242.有效的字母异位词

https://leetcode.cn/problems/valid-anagram/description/
image

class Solution {
public:
    bool isAnagram(string s, string t) {
        if(s.size()!=t.size())
        return false;

        int hash[26] = {0};
        for(int i = 0; i < s.size(); i++)
        {
            hash[s[i] - 'a']++;
        }
        for(int i = 0; i < s.size(); i++)
        {
            hash[t[i] - 'a']--;
        }
        for(int i = 0; i < 26; i++)
        {
            if(hash[i]!=0)
            return false;
        }
        return true;
    }
};

349. 两个数组的交集

https://leetcode.cn/problems/intersection-of-two-arrays/description/
image

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> res;
        unordered_set<int> nums(nums1.begin(),nums1.end());//把nums1全添加进来
        for(int num : nums2)                               //遍历nums2数组
        {
            //nums2的元素在nums1里(也就是nums)出现过
            if(nums.find(num) != nums.end())
            res.insert(num);
        }
        return vector<int> (res.begin(),res.end());
    }
};

383. 赎金信

https://leetcode.cn/problems/ransom-note/
image


class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int len1 = ransomNote.size();
        int len2 = magazine.size();
        if(len1 > len2)
        return false;

        int hash[26] = {0};
        for(int i = 0; i < len2; i++)
        {
            hash[magazine[i]-'a']++;
        }
        for(int i = 0; i < len1; i++)
        {
            hash[ransomNote[i]-'a']--;
        }
        
        for(int i = 0; i < 26; i++)
        {
            if(hash[i] < 0)
            return false;
        }
        return true;
    }
};

49.字母异位词分组

https://leetcode.cn/problems/group-anagrams/description/
image

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        //对所有的string排序,比如bac cba cab 排完序后都是abc, 于是可以用map, abc就是索引, value值就是bac cba cab
        unordered_map<string,vector<string>> mp;
        for(string s : strs) //表示遍历strs的所有string, 这个str是入参
        {
            string cur = s;          //用于记录cur,因为排序完之后就变了
            sort(s.begin(),s.end()); //bac->abc 
            mp[s].push_back(cur);
        }
        vector<vector<string>> res;
        for(auto vs : mp)//一次推入一个vector<string>
        res.push_back(vs.second);
        return res;
    }
};

438.找到字符串中的所有字母异位词

https://leetcode.cn/problems/find-all-anagrams-in-a-string/description/
image

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
        int m = p.size();
        if(m > s.size())return {};

        vector<int> res;
        vector<int> hashs(26),hashp(26);
        for(int i = 0; i < m; i++)
        {
            hashp[p[i]-'a']++;
            hashs[s[i]-'a']++;
        }
        //此刻的hashp[]就是记录了abc有一个a 一个b 一个c
        if(hashp == hashs)
        res.push_back(0);
        for(int i = m; i < s.size(); i++)
        {
            //滑动窗口,右边的加进来,左边的滑出去
            hashs[s[i]-'a']++;
            hashs[s[i-m]-'a']--;

            if(hashp == hashs)
            res.push_back(i-m+1);
        }
        return res;
    }
};

349.两个数组的交集

https://leetcode.cn/problems/intersection-of-two-arrays/
image

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> res;
        unordered_set<int> nums(nums1.begin(),nums1.end());//把nums1全添加进来
        for(int num : nums2)                               //遍历nums2数组
        {
            //nums2的元素在nums1里(也就是nums)出现过
            if(nums.find(num) != nums.end())
            res.insert(num);
        }
        return vector<int> (res.begin(),res.end());
    }
};

350.两个数组的交集Ⅱ

https://leetcode.cn/problems/intersection-of-two-arrays-ii/description/
image

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
        multiset <int> num(nums1.begin(),nums1.end());
        vector <int> res;
        for(int i : nums2)
        {
            if(num.find(i) != num.end())
            {
                res.push_back(i);
                num.erase(num.find(i));
            }
        }
        return res;
    }
};

202. 快乐数

https://leetcode.cn/problems/happy-number/
image

class Solution {
public:
    int getNum(int n)
    {
        int sum = 0;
        while(n)
        {
            int i = n % 10;
            sum += i * i;
            n = n / 10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> nums;
        while(1)
        {
            int sum = getNum(n);
            if(sum == 1)
            return true;

            else if(nums.find(sum)!=nums.end()) //如果不是1,而且已经存在了,说明即将进入无限循环
            return false;

            nums.insert(sum);
            n = sum;
        }
    }
};

1.两数之和

https://leetcode.cn/problems/two-sum/
image

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> map;
        for(int i = 0; i < nums.size(); i++)
        {
            auto it = map.find(target - nums[i]);
            if(it != map.end())
            return {i,it->second}; //这里注意it->second写法!!!

            else
            map.insert(pair<int,int>(nums[i],i)); //pair写法!!
        }
        return {};
    }
};

454.四数相加

https://leetcode.cn/problems/4sum-ii/
image

class Solution {
public:
    int fourSumCount(vector<int>& nums1, vector<int>& nums2, vector<int>& nums3, vector<int>& nums4) {
        int count = 0;
        unordered_map<int,int> um;
        for(int i : nums1)
        {
            for(int j : nums2)
            {
                um[i + j]++;    //没有这个key会自动创建
            }
        }
        for(int i : nums3)
        {
            for(int j : nums4)
            {
                if(um.find(- i - j) != um.end())
                count+=um[-i-j];       //这里需要添加i+j出现的总次数,不能只加一
            }
        }
        return count;
    }
};

15.三数之和

https://leetcode.cn/problems/3sum/description/
image

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        vector<vector<int>> result;
        int left,right;
        for(int i = 0; i < nums.size(); i++)
        {
            if(nums[i] > 0) return result;
            if(i>0 && nums[i]==nums[i-1]) continue;

            left = i + 1;
            right = nums.size() - 1;
            //b c去重直接这样写,会漏掉0 0 0这个三元组!!
            //while(right > left && nums[left]==nums[left++]);
            //while(right > left && nums[right]==nums[right++]); 
            while(right > left)
            {
                //这里一定不可以三个if 保证每次只移动一格,否则会左移后小于右移后又大了 
                if(nums[i]+nums[left]+nums[right] > 0) right--;
                else if(nums[i]+nums[left]+nums[right] < 0) left++;
                else
                {
                    result.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    while(right > left && nums[left]==nums[++left]);
                    while(right > left && nums[right]==nums[--right]);                     
                }
            }
        }
        return result;
    }
};

18.四数之和

https://leetcode.cn/problems/4sum/description/
image

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(), nums.end());
        int left,right;
        for(int i = 0; i < nums.size(); i++)
        {
            //先剪枝再去重,注意剪枝效率,不剪也行 但是慢
            //if(nums[i] > target && target > 0) break; 这样的话 target = -1 ,nums[i] = 0 剪不掉

            if(nums[i] > target && nums[i] >= 0) break;

            if(i > 0 && nums[i] == nums[i-1]) continue;

            for(int j = i + 1; j < nums.size(); j++)
            {
                //if(nums[i] + nums[j] > target && nums[i] + nums[j] >= 0) break; 剪不掉nums[i] = -1 nums[j] = 1
                if(nums[i] + nums[j] > target && nums[j] >= 0) break;

                if(j > i + 1 && nums[j] == nums[j-1]) continue;
                left = j + 1;
                right = nums.size() - 1;
                while(left < right)
                {
                    if((long)nums[i] + nums[j] + nums[left] + nums[right] > target) right--;
                    else if((long)nums[i] + nums[j] + nums[left] + nums[right] < target) left++;
                    else
                    {
                        result.push_back({nums[i], nums[j], nums[left], nums[right]});
                        while(left < right && nums[right] == nums[right - 1]) right--;
                        while(left < right && nums[left] == nums[left + 1]) left++;

                        right--; left++;
                    }
                }
            }
        }
        return result;
    }
};
posted @   __Zed  阅读(10)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示