leetcode题解-49. Group Anagrams
来源:互联网 发布:h5挂机游戏源码 编辑:程序博客网 时间:2024/05/22 18:56
题目:Given an array of strings, group anagrams together.For example, given: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Return: [ [“ate”, “eat”,”tea”], [“nat”,”tan”], [“bat”] ]
思路1,使用前面的题目来判断两个字符串是否为anagrams,这样有两种做法,第一个是循环嵌套,判断字符串间关系,并把已经识别过的字符串记录下来,以免重复判断,代码入下:
public static List<List<String>> groupAnagrams(String[] strs) { List<List<String>> res = new ArrayList<List<String>>(); //存储已经识别过的字符串 Set<Integer> used = new HashSet<>(); for(int i=0; i<strs.length; i++){ if(used.contains(i)) continue; List<String> ana = new ArrayList<>(); used.add(i); ana.add(strs[i]); for(int j=i+1; j<strs.length; j++){ if(used.contains(j)) continue; if(isAnagram1(strs[i], strs[j])){ ana.add(strs[j]); used.add(j); } } res.add(ana); } return res; }
另外一个方法就是,使用hashMap来存储识别过得字符串,然后遍历,对数组中的每一个字符串都使用hashMap的键值进行匹配,这样的缺点是非常耗时。
public static List<List<String>> groupAnagrams2(String[] strs) { List<List<String>> res = new ArrayList<List<String>>(); Map<String, List<String>> used = new HashMap<>(); for(int i=0; i<strs.length; i++){ boolean flag = false; for(String ss : used.keySet()){ if(isAnagram1(strs[i], ss)){ List<String> aa = used.get(ss); aa.add(strs[i]); used.put(ss, aa); flag = true; break; } } if(flag == false){ List<String> aa = new ArrayList<>(); aa.add(strs[i]); used.put(strs[i], aa); } } for(String ss:used.keySet()) res.add(used.get(ss)); return res; }
以上两种方法中的isAnagram1都是之前一个题目中写的效率最高函数。如下。但是发现最终提交结果时都显示超时。说明一开始这种借用之前题目成果的办法并不适用。痛定思痛,接下来想一想有什么改进办法。
public static boolean isAnagram1(String s, String t) { if(s.length() != t.length()) return false; int [] tmp = new int[26]; for(char c : s.toCharArray()) tmp[c-'a'] ++; for(char c:t.toCharArray()) tmp[c-'a'] --; for(int a:tmp) if(a!=0) return false; return true; }
首先按照方法二进行改进,对每个字符串进行遍历的时候,先对其进行排序然后将其作为键值保存到hashMap中,这样就可以省去麻烦的判断过程,而直接使用hashMap.containsKey方法来达到判断的效果。节省了很多循环的时间。但这样的改进带来的提升有限,只击败了15%的用户
public List<List<String>> groupAnagrams3(String[] strs) { if(strs==null || strs.length == 0){ return new ArrayList<List<String>>(); } HashMap<String, List<String>> map = new HashMap<String, List<String>>(); //Arrays.sort(strs); for (String s:strs) { char[] ca = s.toCharArray(); Arrays.sort(ca); String keyStr = String.valueOf(ca); if(!map.containsKey(keyStr)) map.put(keyStr, new ArrayList<String>()); map.get(keyStr).add(s); } for(String key: map.keySet()) { Collections.sort(map.get(key)); } return new ArrayList<List<String>>(map.values()); }
最后,还有一种极为巧妙的方法,使用26个质数与字母一一对应相乘作为字符串的键值保存到hashMap中。这样就省去了字符串的排序等操作,而且这种方法省去了最后对hashMap遍历生成列表的过程也节省了很多时间。这种方法击败了99%的用户。
public List<List<String>> groupAnagrams4(String[] strs) { 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};//最多10609个z List<List<String>> res = new ArrayList<>(); HashMap<Integer, Integer> map = new HashMap<>(); for (String s : strs) { int key = 1; for (char c : s.toCharArray()) { key *= prime[c - 'a']; } List<String> t; if (map.containsKey(key)) { t = res.get(map.get(key)); } else { t = new ArrayList<>(); res.add(t); map.put(key, res.size() - 1); } t.add(s); } return res; }
0 0
- leetcode题解-49. Group Anagrams
- leetcode题解-49. Group Anagrams
- LeetCode题解:Group Anagrams
- 49. Group Anagrams 题解
- [leetcode] 49.Group Anagrams
- LeetCode 49. Group Anagrams
- [LeetCode]49. Group Anagrams
- leetcode 49. Group Anagrams
- 49. Group Anagrams LeetCode
- Leetcode 49. Group Anagrams
- LeetCode 49. Group Anagrams
- LeetCode 49. Group Anagrams
- [leetcode] 49. Group Anagrams
- LeetCode 49. Group Anagrams
- LeetCode-49.Group Anagrams
- [Leetcode] 49. Group Anagrams
- LeetCode - 49. Group Anagrams
- [LeetCode] 49. Group Anagrams
- 想要学习Linux技术,先好好的读一本Linux书籍吧
- doc2vct算法实现
- 无法确定卷版本和状态CHKDSK被终止
- struts2中的exception-mapping声明时异常处理
- POJ-3468-A Simple Problem with Integers(线段树区间修改+区间求和)
- leetcode题解-49. Group Anagrams
- 我有自己的博客了
- 从https的实现看数字证书、SSL、数字签名、摘要算法、对称/非对称加密
- 树莓派3 启动蓝牙并配对
- 文章标题
- Crawler4j学习笔记-util
- 学生信息管理系统+mysql数据库的链接
- ZOJ-2165(DFS)
- 一道素数打表的水题,顺便记下打表高效方法