OJ || 哈希表篇(运用哈希表思想解决字符串问题)

目录

判断是否互为字符重排

题意:

题解:

字母异位词分组

 


判断是否互为字符重排

面试题 01.02. 判定是否互为字符重排 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/check-permutation-lcci/description/

题意:

判断一个字符串是否可以重新排列,得到另一个字符串,相当于统计字符串中每个字母出现的次数,如果两个字符串每个字母出现的次数相等,则互为重排,如果不相等,则无法互为重排。

题解:

我们可以分别遍历两个字符串,用两个哈希表记录每个字母出现的次数,之后再对这两个哈希表进行比较:

1、如果每个字母出现的个数相等,则互为重排。

2、如果存在一个字母出现的次数不相等,则无法互为重排。

考虑到哈希表的消耗较大,我们可以用数组来代替哈希表,同时我们也不需要开 2 个数组,开一个大小为 26 的数组即可。

我们先记录第一个字符串每一个字母出现的次数,把次数记录到数组中,遍历第二个字符串的字母时,直接对刚刚得到的数组对应的字母出现的次数-1。

遍历完第二个字符串后,再去检查数组:

1、如果某一个字母出现的次数不为 0 ,说明这一字母在两个字符串中出现的次数不相等,则两个字符串无法互为重排。

2、如果每个字母的次数都为 0 ,说明这两个字符串可以互为重排。

我们可以在最开始就对这两个字符串的长度进行比较,如果长度不相等,则一定无法互为重排。

class Solution {
public:
    bool CheckPermutation(string s1, string s2) {
        if(s1.size()!=s2.size()) return false;//如果长度不相等,则一定无法互为重排

        int hash[26];
        for(auto x:s1)
            hash[x-'a']++;
        for(auto x:s2)
        {
            hash[x-'a']--;
            if(hash[x-'a']<0) return false;
        }
        for(int i=0;i<26;i++)
        {
            if(hash[i]>0)
                return false;
        }
        return true;
    }
};

字母异位词分组

49. 字母异位词分组 - 力扣(LeetCode)icon-default.png?t=N7T8https://leetcode.cn/problems/group-anagrams/description/

 单从原字符串是很难让计算机去判断谁是字母异位词。从字母异位词的定义上出发,我们可以对每个字符串的字母进行排序,如果是字母异位词,那么它们排序后得到的字符串是相同的,我们就可以根据这一特点来找出谁是字母异位词。

我们可以借助哈希表来解决,哈希表的 key value 是排序后得到的字符串, mapped value 是字母异位词,为了存储多个字母异位词,我们把 mapped value 定义为字符串数组。遍历完 strs 后,就可以得到相应的哈希表。

注意哈希表范围 for 的写法,for ( auto [x,y] : hash ) 可以取出所有的 mapped value!

class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        unordered_map<string,vector<string>> hash;
        for(auto& s:strs)
        {
            string tmp=s;
            sort(tmp.begin(),tmp.end());//对当前字符串排序
            hash[tmp].push_back(s);//插入字母异位词
        }
        vector<vector<string>> ret;//结果
        for(auto [x,y]:hash)//访问哈希表,哈希表的key为x,mapped value为y
        {
            ret.push_back(y);
        }
        return ret;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值