[leetcode] 49.Anagrams

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

Note: All inputs will be in lower-case.
题意:给一个字符串数组,找出其中的所有的anagram组。anagram的意思是不同的单词但是含有相同的字符,这样的单词就称作anagram,比如veil,live,evil,vile。
思路:比如veil,live,evil,vile,对它们的字符进行排序后四者都是eilv,所以很简单的一个想法就是使用hash,hash的键就是排序后的字符串,比如上面提到的eivl。那么对应的值该存什么呢?由于每次都是先对字符串比如(A[i])排序然后查找该排序值temp是否出现过,如果出现那么就将该字符串A[i]存入到anagram的集合中去。但是该anagram组出现的第一个字符串如何处理呢(比如以上,首先扫描到veil的时候将eilv存入到hash中去,但是此时不知道后面是否还会出现排序后是eilv的字符串,所以veil不会放到结果值中去,必须等到后面发现有元素排序后也是eilv才应该将veil存入到结果值中去),最简单的方法从下标0的元素扫描到下标i-1的元素,查看哪个排序后是与temp值相等。但是这是很低效的。比如一个数组前面有一万个非anagram的单词,第10001个是veil,第10002个是live,那么查找veil时需要再扫描10000个,时间复杂度在最差的情况下会变成O(n*n).

解决方法是map的键对应的值保存第一个元素(比如上文提到的veil)。并且加个标志位,使扫描到后面该键时判断是否需要将第一个元素加入,第一个字符串只需要加入一次,加入后就修改该标志位。比如当第一次扫描到veil时存入map[eilv] = “Fveil”,那么接下来扫描到live时由于live排序后也是eilv,所以把live存入结果值,同样把veil存入到结果值中去,并把map[eivl] = “veil”。当扫描到evil时将evil存入,但是不需要将该组第一个元素veil存入,因为veil已经被存入到结果值中去了,判断依据是此时map[eivl]对应的是字符串开头不是’F’。
以上
代码如下:

class Solution {
public:
    vector<string> anagrams(vector<string>& strs) {
      vector<string> result;
      if(strs.size() == 0)return result;
      unordered_map<string,string> dict;
      for(int i = 0; i < strs.size(); i++){
          string temp = strs[i];
          sort(temp.begin(),temp.end());
          if(dict.find(temp) == dict.end())dict[temp] = "F"+strs[i];//'F'means the first element of the anagrams group.
          else {
              result.push_back(strs[i]);
              if(dict[temp].front() == 'F'){
                  dict[temp] = dict[temp].substr(1);
                  result.push_back(dict[temp]);
              }
          }
      }
      return result;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值