No.49 Anagrams[易位构词]

No.49 Anagrams

Given an array of strings, return all groups of strings that are anagrams.

Note: All inputs will be in lower-case.

Tags: Hash Table String
 
难点:
  1、没有读清题意,对易位构词的理解不到位
  2、题意不明了。输入为一系列字符串,别与回文记混淆了
  3、第一次见到,不是很了解,完全没思路
 
具体分析:
  1. 易位构词:两个单词所包含的字符和数量一样,但顺序不同【相当于一组字符的不同序列】
  2. 判断两个单词是否为anagram的方法
    • 法一:使用哈希表:key为字符,value为出现的次数,若两个单词构成的hashmap相同,那么就是anagram。实现起来就是用一个单词构建hashmap,然后用另一个单词对前面的hashmap中的字符逐个去除,最后如果hashmap为空,则返回true。该方法的时间复杂度为O(m+n),m和n分别为另两个单词的长度,而空间复杂度为O(字符集的大小)。
    • 法二:将两个单词排序,若排序后的结果相同,说明两个单词是anagram。该方法的时间复杂度取决于排序算法,一般排序算法时间复杂度为O(nlogn),如果字符集足够小,也可以用线性排序算法。
    • 总体而言,若判断两个单词是否为anagram,方法一要直接简单一些。
  3. 对于本题,是在很多字符串里面按照anagram分类,若使用hashmap的方法,两两匹配,在分组时会比较麻烦;而对于法二使用排序算法,其优势在于可以使用排序后的字符串作为一个key,即一个易位构词类的ID。这样一来,只需要对每个字符串排序,然后建立hashmap,key为排序后的串,value为所有属于这个key类的字符串【灵活一点,可以用字符串数组的索引表示】,这样就可以进行简单的分类。若有n个字符串,字符串最大空间为k,那么该算法的时间复杂度为O(nklogk),其中O(klogk)是对每个字符串进行排序(若用线性算法也可以提高),空间复杂度为O(nk),即hashmap的大小。
  4. 根据返回值,最后还要对hashmap进行整理。

 

  我理解之后提交的代码:

  

 1 #include "stdafx.h"
 2 #include <vector>
 3 #include <string>
 4 #include <map>
 5 #include <algorithm>
 6 #include <iostream>
 7 using namespace std;
 8 
 9 class Solution 
10 {
11 public:
12     vector<string> anagrams(vector<string> &strs) 
13     {
14         map<string,vector<int>> exists;
15         for(int index =0 ; index < strs.size(); index++)//!!!边界
16         {
17             string s;//sort()会改变字符串,故需要临时变量存储
18             s = strs[index];
19             sort(s.begin(), s.end());
20 
21             exists[s].push_back(index);    //直接插入即可
22 
23         }
24         vector<string> result;
25         for(auto const &ip : exists)
26         {
27             if(ip.second.size() > 1)//等于1,没有易位构词;注意表达方式!!!
28             {
29                 for(auto const &it : ip.second)
30                     result.push_back(strs[it]);
31             }
32         }
33 
34         //for(auto it : result)
35         //    cout << it << " ";
36         //cout << endl;
37         return result;
38     }
39 };
40 int main()
41 {
42     Solution sol;
43     string data[] ={"tea","and","ate","nad","eat","dna","dan","tt"};
44     vector<string> test(data,data+8);
45     sol.anagrams(test);
46 
47     return 0;
48 }


网上另一种解法,虽然也能输出,但是,相同易位构词并不会在一类全部输出之后,再输出另一类;但它需要的存储空间比较小

 1 class Solution {
 2 public:
 3     vector<string> anagrams(vector<string> &strs)
 4     {//网上代码
 5         string s;
 6         map<string, int> anagram;
 7         vector<string> res;
 8         for (int i = 0; i < strs.size(); ++i) 
 9         {
10             s = strs[i];
11             sort(s.begin(), s.end());
12             if (anagram.find(s) == anagram.end())
13             {
14                 anagram[s] = i;//第一次出现此类易位构词
15             }
16             else 
17             {
18                 if (anagram[s] >= 0) 
19                 {//此类第二次出现,将第一次输出
20                     res.push_back(strs[anagram[s]]);
21                     anagram[s] = -1;
22                 }
23                 //在本类已存在过的情况下[已置为-1],会输出所有,包括第二次输出的
24                 res.push_back(strs[i]);
25             }
26         }
27         return res;
28     }
29 };
View Code

 

 
 

转载于:https://www.cnblogs.com/dreamrun/p/4527580.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值