- 题目要求
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.
- 题解
题解1 - 双重for
循环(TLE)
题 Two Strings Are Anagrams 的升级版,容易想到的方法为使用双重for
循环两两判断字符串数组是否互为变位字符串。但显然此法的时间复杂度较高。还需要 O(n)O(n) 的数组来记录字符串是否被加入到最终结果中。
1.c++ implement
class Solution{
public:
vector<string> anagrams(vector<string> &strs){
if(strs.size()<2){
return strs;
}
vector<string> result;
vector<bool> visited(strs.size(),false);
for(int s1=0;s1!=strs.size();++s1){
bool has_anagrams=false;
for(int s2=s1+1;s2!=strs.size();++s2){
if((!visited[s2] && isAnagrams(strs[s1],strs[s2]))){
result.push_back(strs[s2]);
visited[strs[s2]]=true;
has_anagrams=true;
}
}
if(!visited[strs[s1]] && has_anagrams){
result.push_back(strs[s1]);
}
}
return result;
}
private:
bool isAnagrams(string &s,string &t){
if(s.size()!=t.size()) return false;
const int AlphaNum=26;
int letterCount[AlphaNum]={0};
for(int i=0;i!=s.size();++i){
++letterCount[s[i]-'a'];
--letterCount[t[i]-'a'];
}
for(int i=0;i!=t.size();++i){
if(letterCount[t[i]-'a']<0){
return false;
}
}
return true;
}
};
- 复杂度分析
私有方法isAnagrams
最坏的时间复杂度为 O(2L)O(2L), 其中 LL 为字符串长度。双重for
循环时间复杂度近似为 \frac {1}{2} O(n^2)21O(n2), nn 为给定字符串数组数目。总的时间复杂度近似为 O(n^2 L)O(n2L). 使用了Vector String "visited",空间复杂度可认为是 O(n)O(n).
- 题解2
在题 Two Strings Are Anagrams 中曾介绍过使用排序和 hashmap 两种方法判断变位词。这里我们将这两种方法同时引入!只不过此时的 hashmap 的 key 为字符串,value 为该字符串在 vector 中出现的次数。两次遍历字符串数组,第一次遍历求得排序后的字符串数量,第二次遍历将排序后相同的字符串取出放入最终结果中。
1.python implement
class Solution:
# @param strs: A list of strings
# @return: A list of strings
# @return: A list of strings
def anagrams(self, strs):
strDict={}
result=[]
for string in strs:
if "".join(sorted(string)) not in strDict.keys():
strDict["".join(sorted(string))] = 1
else:
strDict["".join(sorted(string))] += 1
for string in strs:
if strDict["".join(sorted(string))] >1:
result.append(string)
return result
2.C++ implement
#include <iostream>
#include<vector>
#include<string>
#include<map>
#include<algorithm>
using namespace std;
class Solution {
public:
vector<vector<string>> anagrams(vector<string> &strs) {
map<string, vector<string>> anagram;
vector<vector<string>> result;
for (int i = 0; i < strs.size(); i++) {
string str = strs[i];
sort(str.begin(), str.end());
if (anagram.find(str)==anagram.end()) {
std::vector<string> item;
anagram[str]=item;
}
anagram[str].push_back(strs[i]);
}
map<string,vector<string>> ::iterator it;
for(it=anagram.begin();it!=anagram.end();it++){
result.push_back((*it).second);
}
return result;
}
};
int main()
{
Solution solve;
vector<string> strs;
vector<vector<string>> temp;
strs={"eat", "tea", "tan", "ate", "nat", "bat"};
temp=solve.anagrams(strs);
cout<<"[";
for(int i=0;i<temp.size();i++){
cout<<"[";
for(int j=0;j<temp[i].size();j++){
cout<<"\""<<temp[i][j]<<"\""<<",";
}
cout<<"]";
cout<<endl;
}
cout<<"]";
return 0;
}