C++刷题第五天 哈希表-242.有效的字母异位词 349. 两个数组的交集 202. 快乐数 1. 两数之和

文章介绍了几道编程题的解决方案,均涉及到哈希表的应用。例如,判断两个字符串是否为字母异位词,通过计数数组检查字符出现次数;找到两个数组的交集,利用哈希表记录元素出现状态;判断快乐数,使用哈希表检测数字平方和的重复;以及两数之和问题,通过哈希表快速查找目标值的组合。
摘要由CSDN通过智能技术生成

 242. 有效的字母异位词

给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。

注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。

提示:

  • 1 <= s.length, t.length <= 5 * 104
  • s 和 t 仅包含小写字母

 解题思路:

1、暴力解法,双重for循环,时间复杂度O(n2);

2、哈希表。s.t仅包含小写字母,就可以用一个长为26的数组,记录每个字符串中每个字母出现的次数,然后对比这两个数组元素即可。为了节省空间,可以只定义一个长26值为0的数组,在遍历s的时候元素出现,数组对应位置++;遍历t的时候,数组对应位置++。最后如果该数组有某个元素不为0,则肯定s.t不是字母异位词。

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

342.两个数组的交集

给定两个数组 nums1 和 nums2 ,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。

 解题思路

肯定还是用哈希表,两个数组长度小于1000,并且元素值也在0-1000之间,可以定义一个长为100的数组hush,用来对比nums1和nums2的元素值,如果nums1中含有值为num的元素,就将hash[num]赋值为1,在对比nums2的过程中,如果nums2中含有值为num的元素并且hashnum]已经为1,则num就是两数组共同拥有的元素,循环完之后返回。

class Solution {
public:
    vector<int> intersection(vector<int>& nums1, vector<int>& nums2) {
        unordered_set<int> result_set; // 存放结果,之所以用set是为了给结果集去重
        int hash[1005] = {0}; // 默认数值为0
        for (int num : nums1) { // nums1中出现的字母在hash数组中做记录
            hash[num] = 1;
        }
        for (int num : nums2) { // nums2中出现话,result记录
            if (hash[num] == 1) {
                result_set.insert(num);
            }
        }
        return vector<int>(result_set.begin(), result_set.end());
    }
};

202.快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。

解题思路:

这道题目看上去貌似一道数学问题,其实并不是!

题目中说了会 无限循环,那么也就是说求和的过程中,sum会重复出现,这对解题很重要!

正如:关于哈希表,你该了解这些! (opens new window)中所说,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。

所以这道题目使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止。

判断sum是否重复出现就可以使用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;
            }
            // 如果这个sum曾经出现过,说明已经陷入了无限循环了,立刻return false
            if (set.find(sum) != set.end()) {
                return false;
            } else {
                set.insert(sum);
            }
            n = sum;
        }
    }
};

1. 两数之和

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。

你可以按任意顺序返回答案。

 解题思路:

方法一:暴力解法

一个数组中,找出两个元素值为target的元素下标,双重for循环即可,第一层i=0,第二层j=i+1。

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int i = 0,j = 0;
        for(i=0;i<nums.size();i++){            
            for(j=i+1;j<nums.size();j++){
                if(nums[i]+nums[j] == target)
                    return {i,j};                    
            }           
        }
        return {};
    }
};

方法二:哈希表

定义一个map,key值放数组元素值,value放下标,遍历一遍数组就可以完成,遍历过程中寻找map中是否有target-nums[i]的key,如果有,返回i及该map的value,如果没有就将这个元素加入到map

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 item = map.find(target-nums[i]);
            if (item != map.end())
                return {item->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、付费专栏及课程。

余额充值