Leetcode 49. Group Anagrams (242.Valid Anagram)

valid Anagram

Given two strings s and t, write a function to determine if t is an anagram of s.

For example,
s = "anagram", t = "nagaram", return true.
s = "rat", t = "car", return false.

Note:
You may assume the string contains only lowercase alphabets.

Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?

1、题目分析

解法一:使用一个数组,将a-z这26个字母的出现情况保存下来。第一个字符串出现的单词加一,第二个字符串出现的单词减一。最后保存26的字母的数组为全0,则两个字符串相等。

 1 class Solution {
 2 public:
 3     bool isAnagram(string s, string t) {
 4         if(s.size()!=t.size()){
 5             return false;
 6         }
 7         vector<int> flag(26,0);
 8         for(int i = 0;i<s.size();i++){
 9             flag[s[i]%26]++;
10             flag[t[i]%26]--;
11         }
12         for(int i = 0;i<26;i++){
13             if(flag[i]!=0){
14                 return false;
15             }
16         }
17         return true;
18     }
19 };

Anagram group

这个题目要更复杂一些,需要比较多个字符串,并进行分类排序。

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:

  1. For the return value, each inner list's elements must follow the lexicographic order.
  2. All inputs will be in lower-case.

1、题目分析

超时解法:

1、使用sort函数将每个单词进行排序。        O( N*log(m))

2、然后遍历这个字符串数组,申请一个一维整型数组,将相同的单词编上相同的数字。   O(1)

3、申请一个二维数组 vector<vector<string>>把相同编号的单词放到同一个一维数组中。  O(N*logN)

4、对每一个一维数组进行排序。最终返回结果。  O(N)~O(logN)

时间复杂度分析:sort函数采用快速排序实现,假设n个单词,每个单词m个字母。m比较小,n比较大。

从上面的分析可知,2.遍历数组过程中判断某个单词是新单词还是以前出现过的耗时最长。

 1 class Solution {
 2 public:
 3     vector<vector<string>> groupAnagrams(vector<string>& strs) {
 4         int num = strs.size();
 5         vector<string> strscopy;
 6         vector<string> resultLine;
 7         vector<string> temp;
 8         vector<int> flag(strs.size(),-1);
 9         
10         strscopy.assign(strs.begin(),strs.end());
11         
12         //对每个单词排序
13         for(int i = 0;i<num;i++){
14             sort (strs[i].begin(), strs[i].end()); 
15         }
16         //sort(strs.begin(),strs.end());
17         //使用temp记录相同的元素大类,使用flag记录每个单词摆放的位置。O(m*n)
18         for(int i = 0;i<num;i++){
19             int tag = -1;
20             int j;
21             for(j = 0;j<temp.size();j++){
22                 if(strs[i]==temp[j]){
23                     tag = j;
24                 }
25             }
26             if(tag!=-1){
27                 flag[i] = tag;
28             }else{
29                 temp.push_back(strs[i]);
30                 flag[i] = temp.size()-1;
31             }
32             tag = -1;
33         }
34         vector<vector<string>> result(temp.size(),resultLine);
35         //O(n)
36         for(int i = 0;i<strs.size();i++){
37             result[flag[i]].push_back(strscopy[i]);
38         }
39         //O(m)*O(sort)
40         for(int i = 0;i<result.size();i++){
41             sort(result[i].begin(),result[i].end());
42         }
43         return result;
44 
45     }
46 };

改进解法:

使用unordered_map结构来实现单词分类。上述过程改进为

1、使用sort函数将每个单词进行排序。        O( N*log(m))

2、key值保存排完序的单词,value为字符串数组。          

3、对每个单词排序 O(log(N))

 1   vector<vector<string>> result;
 2         unordered_map<string, vector<string>> hashmap;
 3         //使用sort函数对每个单词排序
 4         for(const auto& i : strs){
 5             string s = i;
 6             sort(s.begin(), s.end());
 7             //使用map结构进行保存
 8             hashmap[s].push_back(i);
 9         }
10         for(const auto& i : hashmap){
11            //i.second表示hashmap的value值
12             vector<string> s = i.second;
13             sort(s.begin(), s.end());
14             result.push_back(s);
15         }
16         return result;  
原文地址:https://www.cnblogs.com/timesdaughter/p/5365569.html