49. Group Anagrams(week3)

49. Group Anagrams

题目描述

Given an array of strings, group anagrams together.

Example:

Input:

["eat", "tea", "tan", "ate", "nat", "bat"]

Output:

[
  ["ate","eat","tea"],
  ["nat","tan"],
  ["bat"]
]

Note:

  • All inputs will be in lowercase.
  • The order of your output does not matter.

解题思路

看到这道题的第一时间,想到的方法自然是先对里面每一个单词进行排序,按照字母顺序排列,然后再判断相等来进行分类。时间复杂度为:排序复杂度 * n个元素:O(),分类复杂度:O(n),总复杂度O()。由于题目没有规定时间复杂度上限和空间复杂度上限,因此这个方法显然是最容易想到的解决方法。然而,我们能不能让时间复杂度稍微低一点呢?

在leetcode的discuss中看到了一个这样的想法:我们要找到拥有相同字母的单词,那么我们可以理解为,这些拥有相同字母的单词拥有相同的“键值”,而它的键值必定和这几个字母有关。那么我们要做的就是找出用这些字母表达出这些独特的键值。利用字母的ASCII值是否可以做到呢?在尝试了+-*/四则运算之后,我发现,纯粹的用ASCII是做不到唯一表达一个字符串的,因此,这时候,我们就要利用更强的哈希方法。将字母的ASCII值分别对应一个素数,然后字符串的键值就可以用这些素数的乘积来表示了。

对于大佬来说,这可能是一个显而易见的方法,但对于萌新而言,这简直是新世界的大门啊!

时间复杂度分析

计算键值O(nl),l是单词的平均长度。分类:O(n)。因此时间复杂度为O(nl)。

空间复杂度分析

哈希函数O(1),分类复杂度:O(n)

源码

class Solution {
public:
    vector> groupAnagrams(vector& strs) {
      int primeNumbers[26] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
            47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101};
      map> weightOfStr;
      if (strs.size() == 0) {
        return vector >{};
      }
      if (strs.size() == 1) {
        return vector >{strs};
      }
      for (auto i : strs) {
        int weight = 1;
        for (int j = 0; j < i.length(); ++j) {
          weight *= primeNumbers[i[j] - 'a'];
        }
        weightOfStr[weight].push_back(i);
      }
      vector >result;
      for (auto i = weightOfStr.begin(); i != weightOfStr.end(); ++i) {
        result.push_back((*i).second);
      }
      return result;
    }
};

你可能感兴趣的:(49. Group Anagrams(week3))