From 0991490c0985aaa60956a1d1d4c6a328fbcf6f80 Mon Sep 17 00:00:00 2001 From: ShusenTang Date: Sat, 20 Jun 2020 10:43:47 +0800 Subject: [PATCH] add solution2 --- solutions/49. Group Anagrams.md | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/solutions/49. Group Anagrams.md b/solutions/49. Group Anagrams.md index 0e46951..25e5b02 100644 --- a/solutions/49. Group Anagrams.md +++ b/solutions/49. Group Anagrams.md @@ -1,5 +1,7 @@ # [49. Group Anagrams](https://leetcode.com/problems/group-anagrams/) # 思路 + +## 思路一 题目要求找出字符串数组里的anagram(同字母异序词),所有的字母都是小写字母。 如何判断两个字符串是否是anagram呢,有两种方法: 1. 先排序再判断排序后的字符串是否相等; @@ -12,9 +14,17 @@ 若strs中有n个字符串,每个字符串长度平均为m,则桶排序时间复杂度为O(m),如果使用的是unordered_map(对应hash)则查找复杂度O(1),所以总体时间复杂度O(mn)。 -注意: unordered_map(对应hash)比map(对应红黑树)快一些,所以使用map的时候如果追求时间复杂度则一律使用unordered_map。 +注意: unordered_map(对应hash)比map(对应红黑树)快一些,所以使用map的时候如果追求时间复杂度则一律使用unordered_map。 + +## 思路二 +讨论区还有一种比较tricky的方法:思路一我们先进行(桶)排序的目的是方便后续判断【26个字母出现次数】是否完全一样,如果一样就是anagram。我们也可以将26个字母用26个不同的素数代替,然后将字符串中所有字母对应的素数乘起来,如果两个字符串最后得到的乘积相等,那么是anagram。 + +注意这个乘积可能很大,亲测long long还会溢出,unsigned long long才不会溢出。所以说此种方法仅供开阔思路。 + +时间复杂度同思路一 # C++ +## 思路一 ``` C++ class Solution { private: @@ -48,3 +58,27 @@ public: } }; ``` +## 思路二 +``` C++ +class Solution { +public: + vector primes = {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}; + vector> groupAnagrams(vector& strs) { + vector>res; + unordered_mapmp; + for(string s: strs){ + unsigned long long hash = 1; + for(char c: s) + hash *= primes[c - 'a']; + + if(!mp.count(hash)){ + res.push_back({s}); + mp[hash] = res.size(); + } + else res[mp[hash] - 1].push_back(s); + } + + return res; + } +}; +```