代码随想录哈希表练习

哈希表是真心不熟。。。感觉得苦战了

目录:

(一)有效的字母异位词

(二)两个数组的交集

(三)快乐数

(一)有效的字母异位词

   这种带字母的数组,尤其还是计算字母出现次数的,优先考虑哈希表

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

力扣其它例题

字母异位词分组(*)

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
      if(strs.size()==0)
         return {};//不用return 0,返回的应该是个字符串
      unordered_map<string,vector<string>> hash;
       for(int i=0;i<strs.size();i++){
           vector<int> tmp(26);
           for(auto c:strs[i]){//在不知道大小的情况下拷贝里面的元素
               tmp[c-'a']++;
           }
            string key(tmp.begin(),tmp.end());//建立一个字符串,囊括tmp
            hash[key].push_back(strs[i]);//使用哈希表存储每一组字母异位词,其中哈希表的键为一组字母异位词的标志,哈希表的值为一组字母异位词列表。
        }
        vector<vector<string>> ans;//建立一个双层vector数组,类似于这种{{"a", "b", "c"}, {"d", "e", "f"}};
        for(auto c:hash){
            vector<string> tmp;
            for(auto k:c.second){
                tmp.push_back(k);//把第二组及以后放入新数组中
            }
            ans.push_back(tmp);
        }
        return ans;
    }
};


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

class Solution {
public:
    vector<int> findAnagrams(string s, string p) {
     vector<int> sout(26);
     vector<int> cout(26);
     int m=p.size();
     if(s.size()<p.size())//首先要判断边界
        return {};
     //用一个数组记录p的字母出现次数
     for(int i=0;i<m;i++){
         sout[p[i]-'a']++;
     }
     //有字串匹配,优先想滑动窗口
     vector<int> ans;
    for(int i=0;i<s.size();i++){
       cout[s[i]-'a']++;
       if(i>=m-1){//解决一长串字符串匹配问题,只有大于等于p时s才可能有字串匹配好,同时,超过了如果没匹配上,ans不计数,cout对应哈希表的次数要减少,相当于滑动窗口first向前移动,i是用来遍历的
           if(cout==sout)  ans.push_back(i-m+1);
           cout[s[i-m+1]-'a']--;
       }
    }
       return ans;
    }
};

(二)两个数组的交集

哈希表最擅长的就是给你一个元素,问别的里面有没有这种问题

需要去重、数字大或者要按照关键字排序的时候,可以考虑用集合set

unordered_set可以直接默认去重,比用数组好

find如果没找到,会直接返回最后一个元素的后一个位置

数组版:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    int hash[1005]={0};
    unordered_set<int> number;
    for(int num:nums1){
        hash[num]=1;
    }
    for(int num:nums2){
        if(hash[num]==1)
           number.insert(num);
    }
    return vector<int>(number.begin(),number.end());//返回时用数组
    }
};

set版:

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
    unordered_set<int> nums_set(nums1.begin(),nums1.end());//直接把nums1存放为set集合
    unordered_set<int> result;//存放去重结果
    for(int num:nums2){
       if (nums_set.find(num) != nums_set.end()) {//这是find的机制
                result.insert(num);
            }
    }
    return vector<int>(result.begin(),result.end());//返回时用数组
    }
};

两个数组的交集Ⅱ

class Solution {
public:
    vector<int> intersect(vector<int>& nums1, vector<int>& nums2) {
    int hash[1005]={0};
    vector<int> ans;
    for(int num:nums1){
        hash[num]++;
    }
    for(int num:nums2){//改一下这里就好
        if(hash[num]>0){//确保选择少的那个
            ans.push_back(num);
            hash[num]--;
        }
    }
    return ans;
    }
};

(三)快乐数

难点主要是要考虑循环条件:当遇到重复值时一定就陷入循环里了。

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;
         else if(set.find(sum)!=set.end()){//若陷入循环则赶紧退出来
             return false;
            }
         else{
             set.insert(sum);
         }
         n=sum;
     }

    }
};

(四)两数之和

力扣第一道题,印象很深刻哈哈

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};//返回两个下标,second指的是数组下标
            }
            // 如果没找到匹配对,就把访问过的元素和下标加入到map中
            map.insert(pair<int, int>(nums[i], i)); 
        }
        return {};
    }
};

(五)四数相加Ⅱ

显然不能用for循环的方法,还是考虑用map哈希表来解决

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值