题目
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
我们先考虑低阶版本,认为字符只有26种可能,然后将a ~ z的字符映射到数组的索引0 ~ 25,数组中存放的则是该索引出现的频次。
记录下s的频次和t的频次,然后比较是否相同,相同则是字母异位词(出现的字母种类一样多且每种出现的频次一样多)。
这里为了节省空间我们选择直接在原数组上进行减法。
代码:
class Solution {
public:int nums[26];bool isAnagram(string s, string t) {//将字符映射到数组上for(int i=0;i<s.size();i++) {int index = s[i] - 'a';nums[index]++;}//for(int i=0;i<t.size();i++) {int index = t[i] - 'a';nums[index]--;}for(int i=0;i<26;i++){if(nums[i]!=0) return false;}return true;}
};
对上面的代码进行时间优化:
class Solution {
public:int nums[26];bool isAnagram(string s, string t) {if(s.size() != t.size()) return false;//将字符映射到数组上for(int i=0;i<s.size();i++) {int index = s[i] - 'a';nums[index]++;}for(int i=0;i<t.size();i++) {int index = t[i] - 'a';nums[index]--;if(nums[index]==-1) return false;}return true;}
};
在遍历数组t的时候,计算nums[index]的值,如果不是异位词汇且两者字符数量一致,在nums数组中必定有差小于0的,这里我们取-1即可。为何不能取>0呢?因为我们是在遍历的过程中从大到小删减频次,所以一开始肯定都是>0的。
对于进阶版本,这边直接贴力扣官方答案:
使用哈希表而不是固定大小的计数器。想象一下,分配一个大的数组来适应整个 Unicode 字符范围,这个范围可能超过 100万。哈希表是一种更通用的解决方案,可以适应任何字符范围。
思路2
我们这边使用c++的容器,不使用数组。但是原理都是一样的。
class Solution {
public:bool isAnagram(string s, string t) {if(s.size() != t.size()) return false;unordered_map<char, int> map;for(int i=0;i<s.size();i++){map[s[i]] ++;}for(int i=0;i<t.size();i++){map[t[i]]--;if(map[t[i]]==-1) return false;}return true;}
};