題目鏈接
49. 字母異位詞分組
題目描述
解題思路
1.暴力法
兩個for循環,分別判斷兩個字符串出現的字母個數是否相同,相同加入同一個List。時間複雜度基本等於O(n^2),Leetcode上提交是超時的。
2.hash法
對暴力法進行改進,利用List記錄字符串出現的字母個數相同的字符串,同時利用hash表記錄List在ans二維列表的下標,這樣只需要遍歷一遍數組即可。
問題來了:hash表的值是下標,那hash表的鍵值該如何表示?
利用大小爲26的數組,並初始化值爲-1,統計每個字母出現的次數,如果兩個字符串符合要求,那麼兩個字符串對應的數組一定是相同的,所以由數組值轉換成的字符串也一定是相同的。所以hash表的鍵值爲數組值轉換成的字符串
3.利用質數實現hash法
解法思路與2相同,首先爲26個字符賦值爲26個質數,因爲質數與質數的乘積是唯一的,這符合hash表鍵值的要求。所以hash表的鍵值爲對應字母的質數乘積。
AC代碼
1.暴力法
class Solution {
public int[] cal(String temp,int[] count){
for(int i = 0; i < temp.length(); i++){
count[temp.charAt(i)-'a']++;
}
return count;
}
public boolean test(int[] countA,int[] countB){
for(int i = 0; i < 26; i++){
if(countA[i] != countB[i]) return false;
}
return true;
}
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> ans = new LinkedList<>();
boolean flags[] = new boolean[strs.length];
for(int i = 0; i < strs.length; i++){
if(flags[i] == true) continue;
List<String> temp = new LinkedList<>();
int countA[] = new int[26];
countA = cal(strs[i],countA);
temp.add(strs[i]);
for(int j = i + 1; j < strs.length; j++){
int countB[] = new int[26];
countB = cal(strs[j],countB);
if(test(countA,countB)){
temp.add(strs[j]);
flags[j] = true;
}
}
ans.add(temp);
}
return ans;
}
}
2.hash表法
class Solution {
public String count(String temp,int[] tot){
StringBuffer sb = new StringBuffer();
for(int i = 0; i < temp.length(); i++){
tot[temp.charAt(i)-'a']++;
}
for(int i = 0; i < tot.length; i++) sb.append(tot[i]);
return sb.toString();
}
public List<List<String>> groupAnagrams(String[] strs) {
List<List<String>> ans = new LinkedList<>();
Map<String,Integer> hashTable = new HashMap<>();
for(int i = 0; i < strs.length; i++){
int[] countN = new int[26];
Arrays.fill(countN,-1);
String str = count(strs[i],countN);
if(hashTable.containsKey(str)){
int index = hashTable.get(str);
ans.get(index).add(strs[i]);
}else{
List<String> temp = new LinkedList<>();
temp.add(strs[i]);
ans.add(temp);
hashTable.put(str,ans.size()-1);
}
}
return ans;
}
}
3.利用質數實現hash法
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map <double,vector<string> > m;
double a[26]={2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101};
for(string& s : strs)
{
double t = 1;
for(char c : s)
t *= a[c - 'a'];
m[t].push_back(s); //t爲單詞對應的質數乘積,m[t]則爲該單詞的異位詞構成的vector
}
for(auto& n : m) //n爲鍵和值組成的pair
res.push_back(n.second);
return res;
}
};