1、字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的字母得到的一个新单词,所有源单词中的字母通常恰好只用一次。
image.png

解法一:暴力/哈希表

简单的暴力算法,题目要求是字母异或词,也就是说异或词的每个字母是相同的,只不过排列的顺序不一样。基于这个,我的想法是:将每个词进行一次排列,那么互为字母异或词的单词经过排列后一定是相等的。所以,先复制一遍输入的词,将他里面的每个词进行一次排序,然后依次找到相同的单词的坐标,把相同的单词加入结果即可得到答案。
步骤:
1、将各个字符串排序
2、遍历每个字符串
3、寻找相同的字符串,并记录下标
4、将相同的字符串添加到结果里

  1. class Solution {
  2. public:
  3. vector<vector<string>> groupAnagrams(vector<string>& strs) {
  4. vector<string> temp = strs;
  5. vector<vector<string>> groudWords;
  6. int len = strs.size();
  7. int *visited = new int[len];
  8. if(len == 0) return groudWords;
  9. for(int i = 0; i < len; i++)
  10. {
  11. sort(temp[i].begin(), temp[i].end());
  12. }
  13. for(int i = 0; i < len; i++)
  14. {
  15. if(visited[i] == 1)
  16. {
  17. continue;
  18. }
  19. groudWords.push_back(attemdGroudWords(temp, strs, i, visited));
  20. }
  21. return groudWords;
  22. }
  23. vector<string> attemdGroudWords(vector<string>& temp, vector<string>& strs, int index, int* visited)
  24. {
  25. vector<string> groudWord;
  26. for(int i = index; i < temp.size(); i++)
  27. {
  28. if(temp[i] != temp[index] || visited[i] == 1)
  29. {
  30. continue;
  31. }
  32. visited[i] = 1;
  33. groudWord.push_back(strs[i]);
  34. }
  35. return groudWord;
  36. }
  37. };

这是我第一次的解法,提交后发现时间复杂度度太大了,关是将每个单词排序的时间复杂度都需要O(n*m)(n是单词数,m是单词的长度)。后来我看了答案发现可以用哈希表进行优化。

  1. class Solution {
  2. public:
  3. vector<vector<string>> groupAnagrams(vector<string>& strs) {
  4. unordered_map<string, vector<string>> mp;
  5. vector<vector<string>> combineWordGroups;
  6. int len = strs.size();
  7. if(len == 0)
  8. return combineWordGroups;
  9. for(int i = 0; i < len; i++)
  10. {
  11. string str = strs[i];
  12. sort(str.begin(), str.end());
  13. mp[str].push_back(strs[i]);
  14. }
  15. int mpLen = mp.size();
  16. for(unordered_map<string, vector<string>>::iterator it = mp.begin(); it != mp.end(); it++)
  17. {
  18. combineWordGroups.push_back(it->second);
  19. }
  20. return combineWordGroups;
  21. }
  22. };

优化后时间复杂度变为O(nklogk),其中n是单词的数量,k是strs中的字符串的最大长度。

解法二:数值替代法。

这个是我在评论区看到的解法,感觉挺有意思的就记录下来了。首先将每个字母定义一个数字,比如a对应的就是1,d对应的是2…,由于互为异或词的单词组成是相同的,那么这两个单词所组成的字母的数字和也一定是相同的,也就是说”abc”和”bca”互为异或词,”abc”对应的数值是1+2+3=6,”bca”对应的数值是2+3+1=6。基于这个规律就可以解出来了。

反思

这道题虽然写对了,思路也和正确答案一样,但是写出来的时间复杂度太高了,没有用最正确的代码将思路表达出来。原因是对数据结构不熟悉,没有一开始就想到哈希表。以后写题的时候会优先考虑数据结构。