代码随想录训练营DAY6| 242.有效的字母异位词 349.两个数组的交集 202.快乐数 1.两数之和

本文介绍了如何使用哈希表来解决编程挑战,包括判断两个字符串是否为字母异位词、找出两个整数数组的交集以及确定是否为快乐数。哈希表提供了高效的数据结构支持,使得在处理这类问题时能快速查找和计数元素。此外,还探讨了在特定情况下如何选择unordered_set来优化空间效率和查找速度。
摘要由CSDN通过智能技术生成

 242.有效的字母异位词

思路:哈希表

定义一个数组 hash[26]初始化为0

小写字母是从 a 到 z 的26个连续元素,s[i] - 'a'可以保证 hash数组下标在0 ~ 26之间

先对 s 字符串的元素做标记++,再在 t 字符串中做标记 - -,如果两字符串的字母元素个数和种类完全相同的话,hash 数组的元素值全为0;反之,若元素为负数或正数,返回 false

bool isAnagram(char * s, char * t){
    int hash[26];
    int i;
    for(i=0;i<26;i++){
        hash[i]=0;
        }
    for(i=0;i<strlen(s);i++){
        hash[s[i]-97]++;
    }
    for(i=0;i<strlen(t);i++){
        hash[t[i]-97]--;
    }
    for(i=0;i<26;i++){
        if(hash[i])
        return false;
    }
    return true;
}

349.两个数组的交集 

自己的思路:找两个数组的交集,用两个哈希表分别标记两数组,注意:这道题只需要找数而不要求数的个数也对应,因此一个哈希表++和- -是不够的

交集存在新定义的数组里

int* intersection(int* nums1, int nums1Size, int* nums2, int nums2Size, int* returnSize){
    int hash[1001]={0};
    int ans[1001]={0};
    int *p=malloc(sizeof(int)*1001);
    int j=0;
    for(int i=0;i<nums1Size;i++){
        hash[nums1[i]]++;
    }
    for(int i=0;i<nums2Size;i++){
         if(hash[nums2[i]]!=0)
         ans[nums2[i]]++;
    }
    for(int i=0;i<1001;i++){
        if(ans[i]>0&&hash[i]>0)
        p[j++]=i;
    }
    *returnSize=j;
    return p;
}

 代码随想录C++版:

当所给数组太大或数据跨越太大(例如:nums1 = {1 ,100 ,1000000}时,会浪费空间,数组哈希表就很不方便

因此选择unordered_set,这个容器可以滤掉重复元素,在返回无重复元素的交集时有用,(比如:nums2中全是‘2’,那么在存元素时,他就能帮我们滤掉重复的2,结果只返回 2);此外,还有 find函数供我们调用来判断 set容器里是否已经存过相同数字,如果有,就说明找到一个交集元素

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

 202.快乐数

依然使用unordered_set,用来判断 sum 是否重复出现

当找到'1'时返回true,遇到重复 sum 时返回 false,如果遇到非重复的 sum ,存入 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;
        int sum;
        while(1){
            sum=getsum(n);
            if(sum==1)
            return true;
            else if(set.find(sum)!=set.end())
            return false;
            else
            set.insert(sum);
            n=sum;
        }
    }
    
};

 1.两数之和

因为要比较元素还要保存目标元素的下标,这时,只能用 unordered_map<int,int>,第一个 int 是元素值,第二个是当前元素下标

判断(target - 当前元素)已经存在 map 中,如果存在,返回当前元素下标 i 和(target - 当前元素)的下标 iter->second

若果没找到就返回空

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++) {
             auto iter = map.find(target-nums[i]);
             if(iter != map.end()){
             return {iter->second,i};
             }
            
             map.insert(pair<int,int>(nums[i],i));
         }
         return {};
    }
};

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值