题目:
Given an array of strings, group anagrams together.
Example:
Input: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
Output:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
Note:
All inputs will be in lowercase.
The order of your output does not matter.
解法1:通过排序法映射
将"ate",“eat”,“tea"排序后都为"aet”,然后将"aet"作为字典的键进行映射
c++:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map<string, vector<string>> hash;
for(string str : strs){
string temp = str;
sort(temp.begin(),temp.end());
hash[temp].push_back(str);
}
for(auto a : hash){
res.push_back(a.second);
}
return res;
}
};
java:
String 不能直接排序,需要转换为字符数组str.toCharArray()
然后字符数组还需要转换为String key = String.valueOf(ca)
另外字典首先要查看键是否存在,不存在首先新建
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> hash = new HashMap<>();
for(String str : strs){
char[] ca = str.toCharArray();
Arrays.sort(ca);
String key = String.valueOf(ca);
if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
hash.get(key).add(str);
}
return new ArrayList<List<String>>(hash.values());
}
}
python:
- collections.defaultdict(list) 生成具有默认空列表的字典
- sorted(s) 进行排序,生成了s的一个副本
- sorted(s) 生成了一个列表,不能作为字典的键,因为列表是可变对象,因此需要转成元组不可变对象
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
ans = collections.defaultdict(list)
for s in strs:
ans[tuple(sorted(s))].append(s)
return ans.values()
解法2;通过字符串中的字符的个数来映射
将26个字母的个数加上/分割形成唯一标识的字符串
c++:
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
vector<vector<string>> res;
unordered_map<string, vector<string>> hash;
for(string str : strs){
vector<int> cnt(26,0);
for(char c : str) cnt[c-'a']++;
string key = "";
for(int d : cnt) key += to_string(d) + "/";
hash[key].push_back(str);
}
for(auto a : hash){
res.push_back(a.second);
}
return res;
}
};
java:
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String, List<String>> hash = new HashMap<>();
int[] count = new int[26];
for(String str : strs){
Arrays.fill(count, 0);
for(char c :str.toCharArray()) count[c-'a']++;
StringBuilder sb = new StringBuilder("");
for(int d : count){
sb.append(d);
sb.append("/");
}
String key = sb.toString();
if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
hash.get(key).add(str);
}
return new ArrayList<List<String>>(hash.values());
}
}
python:
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
ans = collections.defaultdict(list)
for s in strs:
count = [0] * 26
for c in s:
count[ord(c) - ord('a')] += 1
ans[tuple(count)].append(s)
return ans.values()
解法3:
用数字唯一标识
利用算术基本定理。
算术基本定理,又称为正整数的唯一分解定理,即:每个大于1的自然数,要么本身就是质数,要么可以写为2个以上的质数的积,而且这些质因子按大小排列之后,写法仅有一种方式。
用一个数组存储质数 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}。
然后每个字符串的字符减去 ’ a ’ ,然后取到 prime 中对应的质数。把它们累乘(参考49. Group Anagrams)
c++:
有溢出,long long 也不可以,需用unsigned long long
class Solution {
public:
vector<vector<string>> groupAnagrams(vector<string>& strs) {
int prime[26] = { 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 };
vector<vector<string>> res;
unordered_map<long long , vector<string>> hash;
for(string str : strs){
long long key = 1;
for(char c : str) key *= prime[c-'a'];
hash[key].push_back(str);
}
for(auto a : hash){
res.push_back(a.second);
}
return res;
}
};
java:
Integer溢出后处理为负数
class Solution {
public List<List<String>> groupAnagrams(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 };
Map<Integer, List<String>> hash = new HashMap<>();
for(String str : strs){
int key = 1;
for(char c :str.toCharArray()) key *= prime[c-'a'];
System.out.println(key);
if(!hash.containsKey(key)) hash.put(key,new ArrayList<String>());
hash.get(key).add(str);
}
return new ArrayList<List<String>>(hash.values());
}
}
python:
class Solution(object):
def groupAnagrams(self, strs):
"""
:type strs: List[str]
:rtype: List[List[str]]
"""
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 ]
ans = collections.defaultdict(list)
for s in strs:
key = 1
for c in s:
key *= prime[ord(c) - ord('a')]
#print key
ans[key].append(s)
return ans.values()