代码随想录算法训练营第五天 | 题目 LeetCode 242.有效的字母异位词 题目LeetCode349. 两个数组的交集 题目 LeetCode 202. 快乐数 LeetCode1. 两数之和

哈希法常用的三种数据结构:数组、set、map。

    当哈希值较小,范围较小可控时,用数组;当数值很大,使用set;当存在k及对应value时,使用map。

什么时候想到用哈希法?判断一个元素是否出现的时候。

 LeetCode 242.有效的字母异位词

字母异位词:指两字符串长度相同,字母相同,位置不同。

t 是 s 的异位词等价于「两个字符串排序后相等」。

class Solution {
public:
    bool isAnagram(string s, string t) {
        //定义一个数组,存储每个字母出现的次数
        int hash[26]  = {0};
        // for(int i = 0;i < 26;i++){
        //     hash[i] = 0;
        // }
        
        //s[i]-'a'计算出对应字母的下标,如第一个字母时a时,s[0]-'a' = 0
        for(int i =0;i < s.size();i++){
            hash[s[i]-'a']++;
        }
        //对于t中的字母,没出现一次,进行一次--操作
        for(int i = 0;i < t.size();i++){
            hash[t[i]-'a']--;
        }
        //看数组中哪个下表对应的元素不为0;如果大于0,说明该字母s中出现次数多于t;小于0,说明t中出现次数多余s
        for(int i = 0;i < 26;i++){
            if(hash[i] != 0){
                return false;
            }    
        }
    return true;

    }
};

 LeetCode349. 两个数组的交集 

1.使用unordered_set形式的哈希结构

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        //存放结果的集合,由于结果中每个元素是唯一的,而unordered_set具有去重的功能
        unordered_set<int>result_set;
        //选择unorder_set结构存储nums2,即将nums2放入哈希表
        //初始化;
        unordered_set<int>nums_set(nums2.begin(),nums2.end());
        for(int num : nums1){
           // find函数查找元素是否存在,若存在,返回指向该值的迭代器;若不存在,返回set.end()
            if(nums_set.find(num) != nums_set.end()){
                result_set.insert(num);
            }
        }
        //返回一个数组形式,!!!要注意返回值类型是vector
        return vector<int>(result_set.begin(),result_set.end());
        
    }
};

2.使用数组作为哈希法的数据结构 

(1)这里将使用hash数组存储nums1中的元素,并标记其状态存在(1)或者不存在(0),将数组nums1中的元素作为索引。

(2)判断相同的数的逻辑:如果两个数相同,那么nums2中的值也作为hash数组中的一个索引,在hash数组中能够找到对应索引的值,且值为1。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int>result_set; //存放结果
        int hash[1002] = {0};
        //这里将使用hash数组存储nums1中的元素,并标记其状态存在(1)或者不存在(0),将数组nums1中的元素作为索引。
        for(int i = 0;i < nums1.size();i++){
            hash[nums1[i]]=1;   
        }
        //判断相同的数的逻辑:如果两个数相同,那么nums2中的值也作为hash数组中的一个索引,在hash数组中能够找到对应索引的值,且值为1.
        for(int num : nums2){
            if(hash[num] == 1){
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(),result_set.end());
    }
};

 LeetCode 202. 快乐数  

「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为  1,那么这个数就是快乐数。

 取一个正整数n每个的数:

(1)取余:n % 10     取得个位上的数

(2)取商:n /=10      去掉最末尾的数(即去掉个位上的值)

一直重复,可以获得每个位置上的数。

class Solution {
public:
    //计算n的每个位置上的数的平方和
    int getSum(int n){
        int sum = 0;
        while(n){
            int digit = n % 10;       //取余
            sum += digit*digit;        
            n /= 10;               //取商
        }
        return sum;
    }

    bool isHappy(int n) {
        //判段这个数是否重复出现
        unordered_set<int>set;
        while(1){
            int sum = getSum(n);
            if(sum == 1){
                return true;
            }
            //在set中查找是否有相同的元素
            if(set.find(sum) != set.end()){
                return false;
            }
            else{
                set.insert(sum);
            }
            n = sum;
        }
        
    }
};

LeetCode 1. 两数之和

利用unordered_map接收数据

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        //将未匹配上的值存放
        unordered_map<int,int>m;
        for(int i = 0;i < nums.size(); i++){
            //定义一个指针接收find的返回值
            unordered_map<int,int>::iterator it = m.find(target-nums[i]);
            //如果可以找到对应的值,返回数据元素和对应下标
            if(it != m.end()){
                return{it->second,i};
            }
            //否则,将数据添加到m中
            else{
                m.insert(pair<int,int>(nums[i],i));
            }
        }
        //如果都没找到,返回空
        return {};
        
    }
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值