1. 题目描述
给定两个仅包含小写字母的字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的 字母异位词。
字母异位词定义:两个字符串包含的字母种类和数量完全相同,但顺序可以不同(例如 “listen” 和 “silent”)。
原题链接:[242]
2. 解题思路
使用哈希表的方式实现。
哈希表底层可以用一个数组实现,将两个字符串的字符映射到哈希表的每个索引中,然后依次对比两个哈希表内的元素是否一致即可。
关键在于如何构建哈希函数。
根据题目,两个字符串都只包含小写字母,最多26个小写字母,所以构建哈希表的大小为26即可,字母a放到索引0,字母z放到索引25,依次填入。
而如何将字母放到对应的索引中? 根据代码原理,字符本质上是基于 ASCII 码值的整数,a到z对应是连续的ASCII 码值,所以 ‘a’ - ‘a’是0,‘b’ - ‘a’是1,以此类推可以得到a的索引是0,b的索引是1,c的索引是2…这样就可以将字符串内的字符按规则填入哈希表的对应索引中进行比较。
3. C语言实现
3.1 双哈希表
bool isAnagram(char* s, char* t) {int lens = strlen(s), lent = strlen(t);if(lens != lent)return false;int map1[26] = {0} , map2[26] = {0};for(int i = 0; i < lens; i++){map1[s[i] - 'a'] += 1;map2[t[i] - 'a'] += 1;}for(int i = 0; i < 26; i++){if(map1[i] != map2[i]){return false;}}return true;
}
- 首先判断两个数组的长度是否相等,长度不相等肯定不是字母异位词。
- 定义两个哈希表map1和map2,长度设置为26,初始化全为0。
- for循环遍历两个字符串s和t,s[i] - 'a’即表示字符串s中第i个位置的字符该对应于哈希表map1的第几个索引位置,得到索引之后在map1的相应索引处加1,代表该处有一个元素。
- map2同理。
- for循环遍历map1和map2的26个索引,检查两个哈希表是否一致,不一致则返回false表示两个字符串不是有效的字母异位词。
3.2 单哈希表
上面是用两个哈希表对应两个字符串,遍历到字符时在对应的哈希表内加1计数;可以优化一下,使用全为0的单哈希表,遍历s时在哈希表对应索引增加计数,遍历t时在哈希表对应索引减少技术,最后检查哈希表是不是全为0,如果有的索引还有计数,则说明两个字符串含有数量不一样的字符,不是有效的字母异位词,很好理解。
bool isAnagram(char* s, char* t){int lens = strlen(s);int lent = strlen(t);if(lent != lens)return false;int map[26] = {0};for(int i = 0; i < lens; i++){map[s[i] - 'a'] += 1;}for(int i = 0; i < lens; i++){map[t[i] - 'a'] -= 1;}for(int i = 0; i < 26; i++){if(map[i] != 0)return false;}return true;
}