https://leetcode.com/problems/anagrams/
Given an array of strings, return all groups of strings that are anagrams.
Note: All inputs will be in lower-case.
两种方法,一种方法是判断两个string是不是anagram,见下面注释掉的代码,然后如果是,就把这两个string加入到结果List中,然后把这两位标识成已访问(如把当前)public List<String> anagrams(String[] strs){
List<String> rst = new ArrayList<String>();
if(strs==null || strs.length==0) return rst;
for(int i=0; i<strs.length; i++){
if(strs[i].equals("")) continue;
boolean hasAnagram = false;
for(int j= i+1; j<strs.length; j++){
if(strs[j].equals("")) continue;
if(isAnagram(strs[i], strs[j])){
rst.add(strs[j]);
strs[j] = "";
hasAnagram = true;
}
}
if(hasAnagram){
rst.add(strs[i]);
strs[i] = "";
}
}
return rst;
}
public boolean isAnagram(String s1, String s2){
if(s1 == null || s2 == null) return false;
if(s1.length() != s2.length()) return false;
HashMap<Character, Integer> map = new HashMap<Character, Integer>();
for(int i=0; i<s1.length(); i++){
if(map.containsKey(s1.charAt(i))){
map.put(s1.charAt(i), map.get(s1.charAt(i))+1);
}
else{
map.put(s1.charAt(i), 1);
}
}
for(int i=0; i<s2.length(); i++){
if(map.containsKey(s2.charAt(i))){
int num = map.get(s2.charAt(i));
num--;
if(num<0) return false;
map.put(s2.charAt(i), num);
}
else return false;
}
return true;
}
一是把所有string都排序,然后把排序后的结果作为Key,string本身作为arraylist的元素加入到hashtable中去。
public List<String> anagrams(String[] strs) {
List<String> rst = new ArrayList<String>();
if(strs==null || strs.length==0) return rst;
HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();
for(int i=0; i<strs.length; i++){
char[] str = strs[i].toCharArray();
Arrays.sort(str);
String sorted = new String(str);
if(map.containsKey(sorted)){
map.get(sorted).add(strs[i]);
}
else{
ArrayList<String> tmp = new ArrayList<String>();
tmp.add(strs[i]);
map.put(sorted, tmp);
}
}
for(ArrayList<String> list : map.values()){
if(list.size()>1) rst.addAll(list);
}
return rst;
}
这种方法虽然要排序,但是对于本身比较小的string来说,O(nlgn)不会太大,而且对于数组长度n来说,时间复杂度是O(n),因此这种方法更快一些。
面试的时候要认真分析到底哪种方法比较快,再写,不要想当然地觉得排序就比较慢。