先理解下什么是字母异位词。如果两个只包含字母的字符串中所含的字母出现的频率相同,就是字母异位词。
解法一:对两个字符串进行排序,然后比较两个字符串是否相等,排序时间复杂度O(nlogn)
public boolean isAnagram2(String s, String t) {
if (s.length() != t.length()) {
return false;
}
char[] str1 = s.toCharArray();
char[] str2 = t.toCharArray();
Arrays.sort(str1);
Arrays.sort(str2);
return Arrays.equals(str1, str2);
}
解法二:使用hash统计词频
public boolean isAnagram(String s, String t) {
//key是字符,value是次数
Map<Character, Integer> map = new HashMap<>();
char[] sArray = s.toCharArray();
char[] tArray = t.toCharArray();
if(sArray.length!=tArray.length) {
return false;
}
//统计字符串s中每个字符的次数
for(char c : sArray) {
if(map.containsKey(c)) {
map.put(c, map.get(c)+1);
} else {
map.put(c, 1);
}
}
for(char c : tArray) {
if(map.containsKey(c)) {
if(map.get(c)==1) {
map.remove(c);
} else {
map.put(c, map.get(c)-1);
}
} else {
return false;
}
}
return map.isEmpty();
}
解法三:注意到题目中给出限定,字符串中只包含小写字母,可以针对这点进行改进;小写字母是a-z。对比解法二,相当于自定义了哈希函数,a->0,b->1,.....z->25;哈希函数就是int value = inputChar - 'a';直接用一个包含26个元素的数组,数组小标对应的就是字符,下标0对应a,小标1对应b;元素值就是字母对应的频率
public boolean isAnagram3(String s, String t) {
char[] sArray = s.toCharArray();
char[] tArray = t.toCharArray();
if(sArray.length!=tArray.length) {
return false;
}
int[] counter = new int[26];
for(char c : sArray) {
counter[c - 'a'] ++;
}
for(char c : tArray) {
counter[c - 'a'] --;
if(counter[c - 'a'] < 0) {
return false;
}
}
return true;
}
这个思路和计数排序里面用到的“计数”方式差不多;适合数据范围不大的场景
题目进阶中说如果字符包含unicode字符,如果是unicode 4字节形势,超过百万,就不适合用这种方式了