題目
給出一個字符串數組S,找到其中所有的亂序字符串(Anagram)。如果一個字符串是亂序字符串,那么他存在一個字母集合相同,但順序不同的字符串也在S中。
注意事項
所有的字符串都只包含小寫字母
樣例
對于字符串數組 ["lint","intl","inlt","code"]
返回 ["lint","inlt","intl"]
分析
通過hash的思想,我們就是要計算出一個字符串出現的字符以及每個字符出現的次數,如果一樣,則說明,兩個字符就是Anagram。我們可以寫一個hash函數,將每個字符串轉換成字母加數字的形式。
比如,lintt,的hash就是i1l1n1t2,這樣就可以判斷兩個字符是不是Anagram。
再利用hashmap的特性,我們很容易實現這個算法,具體看代碼
代碼
public class Solution {
/**
* @param strs: A list of strings
* @return: A list of strings
*/
public ArrayList<String> anagrams(String[] strs) {
HashMap<String,ArrayList<String>> hash = new HashMap<>();
for(String str : strs) {
// create unique label for each string
String key = generalLabel(str);
// map the label to a list of anagrams
if(!hash.containsKey(key)) {
ArrayList<String> temp = new ArrayList<>();
hash.put(key, temp);
temp.add(str);
}
else {
hash.get(key).add(str);
}
}
ArrayList<String> res = new ArrayList<>();
for(ArrayList<String> anagram : hash.values()) {
// ignore strings without anagrams
if(anagram.size() > 1)
res.addAll(anagram);
}
return res;
}
/*
* create a unique label for a string
* "cat", "atc" => a1c1t1
*/
private String generalLabel(String str) {
int[] hash = new int[26];
for(int i=0;i<str.length();i++) {
int idx = (int)(str.charAt(i)-'a');
hash[idx]++;
}
StringBuilder sb = new StringBuilder();
for(int i=0;i<26;i++) {
if(hash[i] == 0)
continue;
char c = (char)('a' + i);
sb.append(c);
sb.append(hash[i]);
}
return sb.toString();
}
}