題目
給定兩個字符串 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;}
};