Given an array of strings, group anagrams together.
For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
Return:
[ ["ate", "eat","tea"], ["nat","tan"], ["bat"] ]
Note: All inputs will be in lower-case.
题意:给定一个字符串数组,要求我们把字符相同且对应字符数目相同的字符串放在同一个集合中。如上述的例子。
这个题从思路上来说还是比较简单,我们只要判断2个字符串是否是同一类型即可
下面贴代码:
public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> list = new ArrayList<>();
List<String> l = new ArrayList<>();
for(String s : strs){
l.add(s);
}
Iterator<String> iter = l.iterator();
while(!l.isEmpty()){ //循环从集合中取出字符串
List<String> l1 = new ArrayList<>();
String s = l.get(0);
l1.add(s);
l.remove(0);
Iterator<String> iter1 = l.iterator();
while(iter1.hasNext()){ //将由相同字符组成的字符串放在同一个集合l1中
String ss = iter1.next();
if(fon(s,ss)){
l1.add(ss);
iter1.remove();
}
}
list.add(l1);
}
return list;
}
public boolean fon(String s1, String s2){ //判断2个字符串是否是由相同字符组成的。
if(s1.length() != s2.length())
return false;
byte[] b1 = s1.getBytes(); //先把字符串转化为byte数组,然后将byte数组排序,最后再转化成字符串
byte[] b2 = s2.getBytes();
Arrays.sort(b1);
Arrays.sort(b2);
s1 = new String(b1);
s2 = new String(b2);
if(s1.equals(s2))
return true;
return false;
}
}
这样的一个方法是我们首先想到的,但是时间复杂度比较高,在LeetCode上case通过率为99//101,最后的2个case由于数组中元素过多,且字符串较长,运行会出现超时的情况,显然这并不是一种很好的的方法。
我们借鉴一下讨论区的思路,借用hashmap这种数据结构得以优化,大体思路不变
public class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> list = new ArrayList<>();
if(strs == null || strs.length == 0)
return list;
Map<String, List<String>> map = new HashMap<>(); //定义一个map,排序之后的字符串作为key,list作为value,存储由相同字符组成的字符串
for(String s : strs){
char[] ch = s.toCharArray();
Arrays.sort(ch);
String keys = new String(ch);
if(!map.containsKey(keys))
map.put(keys,new ArrayList<String>()); //排序之后的字符串作为key,并且new一个新的list作为value
map.get(keys).add(s); //原字符串存储到value中
}
return new ArrayList<List<String>>(map.values());
}
}
运行时间超过了90.73%,很不错的数据,不过这是参考了他人的想法,自己仍需努力!