leetcode-49、字母异位词分组之奇妙解答
题目链接
这道题目看了官方的解答,实现一遍发现速度很慢,只击败了26%的人,偶然间发现提交后可以看比你快的代码(具体路径:提交记录->通过->放大执行时间靠前的区域->点击最前的一块直方图即可看到示例代码)。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
int n = strs.length;
List<List<String>> res = new ArrayList<>();
HashMap<Long, Integer> map = new HashMap<>();
int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101};
for(int i = 0; i < n; ++i){
String str = strs[i];
long hashcode = getHashcode(str, primes);
if(map.containsKey(hashcode)){
res.get(map.get(hashcode)).add(str);
continue;
}
res.add(new ArrayList<String>());
map.put(hashcode, res.size() - 1);
res.get(res.size() - 1).add(str);
}
return res;
}
private long getHashcode(String str, int[] primes){
long hashcode = 1;
for(int i = 0; i < str.length(); ++i){
int c = primes[str.charAt(i) - 'a'];
hashcode *= c;
}
return hashcode;
}
}
-
这位高手没有采用jdk提供的哈希函数,而是自己定义了一个hash函数,通过设置26个素数,每个代表一个小写字母,如果是字母异位的话,这些字母的乘积一样,而且因为是素数的原因,所以不会产生不是字母异位的字符串得到的hash值一样的情况。
-
还是一流程序员写源码,二流用jdk啊,哈哈哈哈。对他的代码进行个小改动,简洁点如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
// @lc code=start
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
if(strs.length==0) return new ArrayList();
HashMap<Long, List> map = new HashMap<>();
int[] primes = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29,
31, 37, 41, 43, 47, 53, 59, 61, 67, 71,
73, 79, 83, 89, 97, 101};
for(String str:strs){
long hashcode = getHashcode(str, primes);
if(map.containsKey(hashcode)==false){
map.put(hashcode, new ArrayList());
}
map.get(hashcode).add(str);
}
return new ArrayList(map.values());
}
private long getHashcode(String str, int[] primes){
long hashcode = 1;
for(int i = 0; i < str.length(); ++i){
int c = primes[str.charAt(i) - 'a'];
hashcode *= c;
}
return hashcode;
}
}
// @lc code=end
这里用到map的一个values方法,能将其里面所有的key对应的values值(List集合)输出,然后用ArrayList的构造函数进行返回。这样代码简洁的多了,条理也清晰。