LeetCode-49. Group Anagrams
Given an array of strings, group anagrams together.
Example:
Input: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]
Note:
- All inputs will be in lowercase.
- The order of your output does not matter.
针对每个字符串,和当前所有group的第一个字符串比较,字符串比较使用map,不是最优解。
1 class Solution { 2 public List<List<String>> groupAnagrams(String[] strs) {//my 3 List<List<String>> re = new ArrayList<>(); 4 for (int i = 0; i < strs.length; i++) { 5 if(0==i){ 6 List<String> group = new ArrayList<>(); 7 group.add(strs[0]); 8 re.add(group); 9 } 10 else{ 11 int flag = 0; 12 for (int j = 0; j < re.size(); j++) { 13 if(isAnagram(strs[i],re.get(j).get(0))){ 14 re.get(j).add(strs[i]); 15 flag= 1; 16 } 17 } 18 if(0==flag){ 19 List<String> group = new ArrayList<>(); 20 group.add(strs[i]); 21 re.add(group); 22 } 23 } 24 } 25 return re; 26 } 27 private boolean isAnagram(String s, String t) { 28 if(null==s&&null==t){ 29 return true; 30 } 31 if(null==s||null==t||s.length()!=t.length()){ 32 return false; 33 } 34 Map<Character,Integer> map = new HashMap<>(); 35 for (int i = 0; i < s.length(); i++) { 36 char c= s.charAt(i); 37 if(map.containsKey(c)){ 38 map.put(c,map.get(c)+1); 39 } 40 else{ 41 map.put(c,1); 42 } 43 } 44 for (int i = 0; i < t.length(); i++) { 45 char c= t.charAt(i); 46 if(map.containsKey(c)){ 47 map.put(c,map.get(c)-1); 48 if(map.get(c)==0){ 49 map.remove(c); 50 } 51 } 52 else{ 53 return false; 54 } 55 } 56 return true; 57 } 58 }
优解思路是为每个group,设置一个唯一的hashcode,即map的key,然后讲字符串映射为哈希值并判断,所以哈希函数的设计决定了算法的时间复杂度,字符串长度为k,字符串个数为n。
- 排序,key为排序后的字符串,但时间复杂度最优为O(nklogk)
- 拼接字符串,key为使用特殊字符分割的26个数字,每个数值表示当前字母出现的次数,如#2#1#0#0...#0表示aab,时间复杂度为O(nk)
- 素数,key为一个整数,每个字母使用一个素数表示,key为每个字母所表示素数的乘积,如12=2*2*3表示aab,时间复杂度为O(nk)
问题的关键是找到一个较优的唯一映射关系。
1 public List<List<String>> groupAnagrams(String[] strs) {//哈希 map mytip 2 List<List<String>> re = new ArrayList<>(); 3 int[] prime={2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103};//素数代表一个字母 4 Map<Integer,Integer> map=new HashMap<>(); 5 for (int i = 0; i < strs.length; i++) { 6 int code = 1; 7 for (int j = 0; j < strs[i].length(); j++) { 8 code*=prime[strs[i].charAt(j)-'a']; 9 } 10 if(map.containsKey(code)){ 11 re.get(map.get(code)).add(strs[i]); 12 } 13 else { 14 List<String> group = new ArrayList<>(); 15 group.add(strs[i]); 16 map.put(code,re.size()); 17 re.add(group); 18 } 19 } 20 return re; 21 } 22
相关题
有效的字母异位词 LeetCode242 https://www.cnblogs.com/zhacai/p/10574647.html
进阶题
查找所有异位词 LeetCode438 https://www.cnblogs.com/zhacai/p/10596274.html