题目
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
桶思想,但只有70%
def isAnagram(self, s: str, t: str) -> bool:
if len(s)!= len(t): return False
in_s = [0]*26
in_t = [0]*26
for i,j in zip(s,t):
in_s[ord(i)-ord('a')] += 1
in_t[ord(j)-ord('a')] += 1
for i in range(26):
if in_s[i]!=in_t[i]:
return False
return True
用counter优化了下代码,但是效率还是不理想
def isAnagram(self, s: str, t: str) -> bool:
if len(s)!= len(t): return False
counter = [0]*26
for i,j in zip(s,t):
counter[ord(i)-ord('a')] += 1
counter[ord(j)-ord('a')] -= 1
for i in range(26):
if counter[i]!=0:
return False
return True
再优化,第一次记录s,第二次记录t的同时判断,如果小于1那就证明t有比s多的字符(长度相等,没有多的那就没有少的)
def isAnagram(self, s: str, t: str) -> bool:
if len(s)!= len(t): return False
counter = [0]*26
for i in s:
counter[ord(i)-ord('a')] += 1
for j in t:
counter[ord(j)-ord('a')] -= 1
if counter[ord(j)-ord('a')] < 0: # 包含了s没有的字符
return False
return True
这个方法更适合哈希表
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
d = {}
for c in s:
d[c] = d.get(c, 0) + 1
for c in t:
d[c] = d.get(c, 0) - 1
if d[c] < 0:
return False
return True
使用哈希表而不是固定大小的计数器。想象一下,分配一个大的数组来适应整个 Unicode 字符范围,这个范围可能超过 100万。哈希表是一种更通用的解决方案,可以适应任何字符范围。
不得不惊叹C++的效率,击败 python100% 击败 c++20%
bool isAnagram(string s, string t) {
if (s.size() != t.size()) return false;
unordered_map<int, int> umap;
for (char ch : s) ++umap[ch];
for (char ch : t) {
umap[ch]--;
if(umap[ch]<0) return false;
}
return true;
}
bool isAnagram(string s, string t) {
if (s.size() != t.size()) return false;
unordered_map<int, int> umap;
for(int i=0;i<s.size();i++){
umap[s[i]]++;
umap[t[i]]--;
}
for(auto ch : umap){
if(ch.second!=0) return false;
}
return true;
}
用vector模拟hash,但是还是哈希的适用程度更广
bool isAnagram(string s, string t) {
if(s.size()!=t.size()) return false;
vector<int> counter(26);
for(int i=0;i<s.size();i++){
counter[s[i]-'a']++;
counter[t[i]-'a']--;
}
for(int n:counter)
if(n!=0)
return false;
return true;
}