今天leecode看到了道初级算法题。感觉思维很精妙。特此记录下来以供学习使用
一、有效的字母异位词
字母异位词就是两个字符串的字母相同,个数相同,顺序可以不管。
1 暴力破解
我的思维就是:使用map统计每一个字母的个数,然后遍历两个map。进行对比。两个map的嵌套遍历,时间复杂度O(N²)。空间复杂度是O(N)。
代码如下:
public boolean isAnagram(String s, String t) {
if (s.length() != t.length())
return false;
if (s.length() == 0) {
return true;
}
Map<Character,Integer> ms=new HashMap<>();
Map<Character,Integer> mt=new HashMap<>();
char[] chs = s.toCharArray();
char[] cht = t.toCharArray();
for (int i=0;i<chs.length;i++){
ms.put(chs[i],ms.getOrDefault(chs[i],0)+1);
}
for (int j=0;j<cht.length;j++){
mt.put(cht[j],mt.getOrDefault(cht[j],0)+1);
}
for (Map.Entry<Character,Integer> s1:ms.entrySet()){
for(Map.Entry<Character,Integer> s2:mt.entrySet()){
Character key = s1.getKey();
if(mt.get(key)==null || !mt.get(key).equals(s1.getValue())){
return false;
}
}
}
return true;
}
从统计结果来看,时间用时才击败了26%不到。
2 利用Arrays
对两个字符数组排序,然后判断两个数组是否相等。这个也可以解决。时间复杂度取决于排序算法。平均是O(nlogn)
public boolean isAnagram(String s, String t) {
//特判,长度不同必定不是
if (s.length()!=t.length()) return false;
//两个字符串排序后是否相等
char[] array1 = s.toCharArray();
char[] array2 = t.toCharArray();
Arrays.sort(array1);
Arrays.sort(array2);
return Arrays.equals(array1,array2);
}
这个就已经很厉害了。
3 自定义Hash运算
首先转化两个字符串为字符数组。定义一个长度为26的字符数组。存储的是s中对应的每个字母对应的Ascii码表值和a的码表值得差。如果有多个,就自增。t恰好自减。最后看这个数组是否都为0;
public static boolean isAnagram(String s, String t) {
//总共有26个字母
char[] arr = new char[26];
char[] chs = s.toCharArray();
char[] cht = t.toCharArray();
//
for (int i = 0; i < chs.length; i++) {
arr[chs[i] - 'a']++;
}
for (int j = 0; j < cht.length; j++) {
arr[cht[j] - 'a']--;
}
for (int k = 0; k < 26; k++) {
if (arr[k] != 0) {
return false;
}
}
return true;
}