代码随想录算法训练营刷题复习12:哈希表

哈希表系列

  1. 242. 有效的字母异位词
  2. 349. 两个数组的交集
  3. 202. 快乐数
  4. 1. 两数之和
  5. 454. 四数相加 II
  6. 15. 三数之和
  7. 383. 赎金信
  8. 18. 四数之和

242. 有效的字母异位词
s与t都仅包含小写字母,可以使用数组存储二十六个英文字母出现的次数

class Solution {
public:
    bool isAnagram(string s, string t) {
        int abc[26] = {0};

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

349. 两个数组的交集

unordered_map与unordered_set的区别与联系:
相同点,都是存储不重复的元素
不同点,unordered_map存的是键值对,unordered_set存的是单个的值

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> us;
        unordered_set<int> us_nums2(nums2.begin(),nums2.end());
        for(int i=0;i<nums1.size();i++) {
            if(us_nums2.find(nums1[i]) != us_nums2.end()) {
                us.insert(nums1[i]);
            }
        }
        return vector<int>(us.begin(),us.end());
    }
};

202. 快乐数

使用unordered_set记录元素是否循环出现

class Solution {
public:
    int getSum(int n) {
        int sum = 0;
        while(n) {
            sum+=(n%10)*(n%10);
            n/=10;
        }
        return sum;
    }
    bool isHappy(int n) {
        unordered_set<int> set;
        while(1) {
            int sum = getSum(n);
            if(sum==1)
                return true;
            if(set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n=sum;
        }
    }
};

1. 两数之和

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int,int> umap;
        for(int i=0;i<nums.size();i++) {
            auto it = umap.find(target-nums[i]);
            if(it != umap.end())
                return {it->second,i};
            umap.insert(pair<int,int>(nums[i],i));
        }
        return {};
    }
};

454. 四数相加 II

class Solution {
public:
    int fourSumCount(vector<int>& A, vector<int>& B, vector<int>& C, vector<int>& D) {
        unordered_map<int,int> umap;
        for(int a:A) {
            for(int b:B) {
                umap[a+b]++;
            }
        }
        int count =0;
        for(int c : C) {
            for(int d : D) {
                if(umap.find(0-(c+d))!=umap.end()) {
                    count += umap[0-c-d];
                }
            }
        }
        return count;
    }
};

15. 三数之和

class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        int size = nums.size();
        if(size<3)
            return {};
        vector<vector<int>> res;
        sort(nums.begin(),nums.end());
        for(int i=0;i<size;i++)
        {
            if(nums[i]>0)
                return res;
            if(i>0 && nums[i]==nums[i-1])
                continue;
            int left = i+1;
            int right = size-1;
            while(left<right)
            {
                if(nums[left]+nums[right] > -nums[i])    //两数之和大,右指针向左移
                    right--;
                else if(nums[left]+nums[right] < -nums[i])   //两数之和小,左指针向右移
                    left++;
                else{
                    //找到了就把他加进去,创建一个临时的一维数组,加入到二维数组中的一项
                    res.push_back(vector<int>{nums[i],nums[left],nums[right]});
                    left++;
                    right--;
                    //去重,不考虑重复元素
                    while(left<right && nums[left]==nums[left-1])
                        left++;
                    while(left<right && nums[right]==nums[right+1])
                        right--;
                    
                }

            }
        }
        return res;
    }
};

383. 赎金信

class Solution {
public:
    bool canConstruct(string ransomNote, string magazine) {
        int record[26] = {0};
        for(int i=0;magazine[i]!='\0';i++)
        {
                record[magazine[i]-'a']++;
        }
        for(int i=0;ransomNote[i]!='\0';i++)
        {
            if(record[ransomNote[i]-'a']!=0)
                record[ransomNote[i]-'a']--;
            else if(record[ransomNote[i]-'a']==0)
                return false;
        }
        return true;
    }
};

18. 四数之和

class Solution {
public:
    vector<vector<int>> fourSum(vector<int>& nums, int target) {
        vector<vector<int>> result;
        sort(nums.begin(),nums.end());
        for(int k=0;k<nums.size();k++)
        {
            //剪枝
            if(nums[k]>target && nums[k]>=0)        //排除和为负数而漏掉解
                break;
            //对nums[k]去重
            if(k>0 && nums[k] == nums[k-1])         //确保k从第二项开始,有前一项可以比较
                continue;
            for(int i = k+1;i<nums.size();i++)
            {
                //剪枝*2
                if(nums[i]+nums[k]>target && nums[k]+nums[i] >=0)
                    break;
                //从第二个开始判断,是否与前一个值相同
                if(i>k+1 && nums[i] == nums[i-1])       //确保i从第二项开始,有前一项可以比较
                    continue;
                int left = i+1, right = nums.size()-1;      //经典双指针法
                while(left < right)
                {
                    if((long) nums[k]+nums[i]+nums[left]+nums[right] > target)    //大了right往左移
                        right--;
                    else if((long) nums[k]+nums[i]+nums[left]+nums[right] < target)         //小了left往右移
                        left++;
                    else{
                        result.push_back({nums[k],nums[i],nums[left],nums[right]});         //找到之后用push_back把一维数组的三个值作为二维的一项装入
                        while(right > left && nums[right] == nums[right-1])         //去重
                            right--;
                        while(right > left && nums[left] == nums[left+1])           //去重
                            left--;
                        right--;
                        left++;
                    }
                }
            }
        }
        return result;
    }
};

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值