题目: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; } };