• 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.

     
    难点:
      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
     
     
  • 相关阅读:
    初识SpringBoot
    Dubbo案例SSM整合
    Dubbo
    Spring错题整合
    SSM整合
    SpringMVC数据校验
    SpringMVC拦截器
    SpringMVC文件上传
    SpringMVC异常
    字符串
  • 原文地址:https://www.cnblogs.com/dreamrun/p/4527580.html
Copyright © 2020-2023  润新知