題目:Given an array of strings, group anagrams together.
For example, given: ["eat", "tea", "tan", "ate", "nat", "bat"]
,
Return:
Note: All inputs will
be in lower-case.
題意:對字符串集進行分類的一道題目,若是兩個字符串出現的所有字母相同,且出現的頻率相同,則把這兩個字符串歸爲一組,同一組中字符串按照字幕的升序進行排列。
剛開始我做這道題的時候,判斷兩個字符串是否爲一組的時候用的排序,同時對兩個字符串按照升序進行排序,若排序後兩個字符串相同,則把兩個字符串歸爲一組,但是這種方法超時了,就是因爲對字符串排序的時候耗費了大量時間(可能一個字符串會非常長),因此不得不採取另一個方法,那就是用map來判斷兩個字符串是否爲一組。
我們可以申請這樣一個map<char,int>數組,對字符串中出現的字母分別統計其頻數,只要對應字母頻數頻數相同,即可歸爲一組。這種方法相比排序來說,減少了一層內層循環,因此時間複雜度被大大降低了。
一種c++的實現如下:
#include<iostream>
#include<string>
#include<vector>
#include<map>
using namespace std;
class Solution {
public:
vector<vector<string> > groupAnagrams(vector<string>& strs) {
vector<vector<string> > res;
vector<map<char,int> > alphabet;
for(int i = 0; i < strs.size(); i++) {
//如果結果爲空,直接插入
if(res.empty()) {
vector<string> v;
v.push_back(strs[0]);
res.push_back(v);
map<char,int> ma;
//統計該字符串的頻數
for(int z = 0; z < strs[0].size(); z++) {
ma[strs[0][z]]++;
}
alphabet.push_back(ma);
} else {
map<char,int> ma1;
for(int z = 0; z < strs[i].size(); z++) {
ma1[strs[i][z]]++;
}
bool is = false;
for(int j = 0; j < alphabet.size(); j++) {
//如果該字符串在結果中有相同的組。則插入
if(ma1 == alphabet[j]) {
is = true;
int k = 0;
//定位插入的位置
while(strs[i] > res[j][k]) {
k++;
if(k == res[j].size()) {
break;
}
}
vector<string>::iterator it;
it = res[j].begin();
for(int m = 0; m < k; m++) {
it++;
}
res[j].insert(it,strs[i]);
break;
}
}
//該字符串在結果中沒有找到對應的組,創建新的組
if(is == false ) {
vector<string> v;
v.push_back(strs[i]);
res.push_back(v);
map<char,int> ma;
for(int z = 0; z < strs[i].size(); z++) {
ma[strs[i][z]]++;
}
alphabet.push_back(ma);
}
}
}
return res;
}
};