28
28
29
29
## 解法
30
30
31
- ### 方法一
31
+ ### 方法一:哈希表
32
+
33
+ 1 . 遍历字符串,对每个字符串按照** 字符字典序** 排序,得到一个新的字符串。
34
+ 2 . 以新字符串为 ` key ` ,` [str] ` 为 ` value ` ,存入哈希表当中(` HashMap<String, List<String>> ` )。
35
+ 3 . 后续遍历得到相同 ` key ` 时,将其加入到对应的 ` value ` 当中即可。
36
+
37
+ 以 ` strs = ["eat", "tea", "tan", "ate", "nat", "bat"] ` 为例,遍历结束时,哈希表的状况:
38
+
39
+ | key | value |
40
+ | ------- | ----------------------- |
41
+ | ` "aet" ` | ` ["eat", "tea", "ate"] ` |
42
+ | ` "ant" ` | ` ["tan", "nat"] ` |
43
+ | ` "abt" ` | ` ["bat"] ` |
44
+
45
+ 最后返回哈希表的 ` value ` 列表即可。
46
+
47
+ 时间复杂度 $O(n\times k\times \log k)$。其中 $n$ 和 $k$ 分别是字符串数组的长度和字符串的最大长度。
32
48
33
49
<!-- tabs:start -->
34
50
35
51
``` python
36
52
class Solution :
37
53
def groupAnagrams (self , strs : List[str ]) -> List[List[str ]]:
38
- chars = defaultdict(list )
54
+ d = defaultdict(list )
39
55
for s in strs:
40
- k = ' ' .join(sorted (list (s) ))
41
- chars [k].append(s)
42
- return list (chars .values())
56
+ k = ' ' .join(sorted (s ))
57
+ d [k].append(s)
58
+ return list (d .values())
43
59
```
44
60
45
61
``` java
46
62
class Solution {
47
63
public List<List<String > > groupAnagrams (String [] strs ) {
48
- Map<String , List<String > > chars = new HashMap<> ();
64
+ Map<String , List<String > > d = new HashMap<> ();
49
65
for (String s : strs) {
50
66
char [] t = s. toCharArray();
51
67
Arrays . sort(t);
52
- String k = new String (t);
53
- chars . computeIfAbsent(k, key - > new ArrayList<> ()). add(s);
68
+ String k = String . valueOf (t);
69
+ d . computeIfAbsent(k, key - > new ArrayList<> ()). add(s);
54
70
}
55
- return new ArrayList<> (chars . values());
71
+ return new ArrayList<> (d . values());
56
72
}
57
73
}
58
74
```
@@ -61,68 +77,132 @@ class Solution {
61
77
class Solution {
62
78
public:
63
79
vector<vector<string >> groupAnagrams(vector<string >& strs) {
64
- unordered_map<string, vector<string >> chars ;
65
- for (auto s : strs) {
80
+ unordered_map<string, vector<string >> d ;
81
+ for (auto& s : strs) {
66
82
string k = s;
67
83
sort(k.begin(), k.end());
68
- chars [ k] .emplace_back(s);
84
+ d [ k] .emplace_back(s);
69
85
}
70
- vector<vector<string >> res;
71
- for (auto it = chars.begin(); it != chars.end(); ++it) {
72
- res.emplace_back(it->second);
73
- }
74
- return res;
86
+ vector<vector<string >> ans;
87
+ for (auto& [ _ , v] : d) ans.emplace_back(v);
88
+ return ans;
75
89
}
76
90
};
77
91
```
78
92
79
93
```go
80
- func groupAnagrams(strs []string) [][]string {
81
- chars := map[string][]string{}
94
+ func groupAnagrams(strs []string) (ans [][]string) {
95
+ d := map[string][]string{}
82
96
for _, s := range strs {
83
- key := []byte(s)
84
- sort.Slice(key, func(i, j int) bool {
85
- return key[i] < key[j]
86
- })
87
- chars[string(key)] = append(chars[string(key)], s)
97
+ t := []byte(s)
98
+ sort.Slice(t, func(i, j int) bool { return t[i] < t[j] })
99
+ k := string(t)
100
+ d[k] = append(d[k], s)
88
101
}
89
- var res [][]string
90
- for _, v := range chars {
91
- res = append(res, v)
102
+ for _, v := range d {
103
+ ans = append(ans, v)
92
104
}
93
- return res
105
+ return
94
106
}
95
107
```
96
108
97
109
``` ts
98
110
function groupAnagrams(strs : string []): string [][] {
99
- const map = new Map <string , string []>();
111
+ const d : Map <string , string []> = new Map ();
100
112
for (const s of strs ) {
101
- const k = s .split (' ' ).sort ().join ();
102
- map .set (k , (map .get (k ) || []).concat ([s ]));
113
+ const k = s .split (' ' ).sort ().join (' ' );
114
+ if (! d .has (k )) {
115
+ d .set (k , []);
116
+ }
117
+ d .get (k )! .push (s );
118
+ }
119
+ return Array .from (d .values ());
120
+ }
121
+ ```
122
+
123
+ <!-- tabs: end -->
124
+
125
+ ### 方法二:计数
126
+
127
+ 我们也可以将方法一中的排序部分改为计数,也就是说,将每个字符串 $s$ 中的字符以及出现的次数作为 ` key ` ,将字符串 $s$ 作为 ` value ` 存入哈希表当中。
128
+
129
+ 时间复杂度 $O(n\times (k + C))$。其中 $n$ 和 $k$ 分别是字符串数组的长度和字符串的最大长度,而 $C$ 是字符集的大小,本题中 $C = 26$。
130
+
131
+ <!-- tabs: start -->
132
+
133
+ ``` python
134
+ class Solution :
135
+ def groupAnagrams (self , strs : List[str ]) -> List[List[str ]]:
136
+ d = defaultdict(list )
137
+ for s in strs:
138
+ cnt = [0 ] * 26
139
+ for c in s:
140
+ cnt[ord (c) - ord (' a' )] += 1
141
+ d[tuple (cnt)].append(s)
142
+ return list (d.values())
143
+ ```
144
+
145
+ ``` java
146
+ class Solution {
147
+ public List<List<String > > groupAnagrams (String [] strs ) {
148
+ Map<String , List<String > > d = new HashMap<> ();
149
+ for (String s : strs) {
150
+ int [] cnt = new int [26 ];
151
+ for (int i = 0 ; i < s. length(); ++ i) {
152
+ ++ cnt[s. charAt(i) - ' a' ];
153
+ }
154
+ StringBuilder sb = new StringBuilder ();
155
+ for (int i = 0 ; i < 26 ; ++ i) {
156
+ if (cnt[i] > 0 ) {
157
+ sb. append((char ) (' a' + i)). append(cnt[i]);
158
+ }
159
+ }
160
+ String k = sb. toString();
161
+ d. computeIfAbsent(k, key - > new ArrayList<> ()). add(s);
162
+ }
163
+ return new ArrayList<> (d. values());
103
164
}
104
- return [... map .values ()];
105
165
}
106
166
```
107
167
108
- ``` rust
109
- use std :: collections :: HashMap ;
110
-
111
- impl Solution {
112
- pub fn group_anagrams (strs : Vec <String >) -> Vec <Vec <String >> {
113
- let mut map = HashMap :: new ();
114
- for s in strs {
115
- let key = {
116
- let mut cs = s . chars (). collect :: <Vec <char >>();
117
- cs . sort ();
118
- cs . iter (). collect :: <String >()
119
- };
120
- map . entry (key )
121
- . or_insert (vec! [])
122
- . push (s );
168
+ ``` cpp
169
+ class Solution {
170
+ public:
171
+ vector<vector<string >> groupAnagrams(vector<string >& strs) {
172
+ unordered_map<string, vector<string >> d;
173
+ for (auto& s : strs) {
174
+ int cnt[ 26] = {0};
175
+ for (auto& c : s) ++cnt[ c - 'a'] ;
176
+ string k;
177
+ for (int i = 0; i < 26; ++i) {
178
+ if (cnt[ i] ) {
179
+ k += 'a' + i;
180
+ k += to_string(cnt[ i] );
181
+ }
182
+ }
183
+ d[ k] .emplace_back(s);
123
184
}
124
- map . into_values (). collect ()
185
+ vector<vector<string >> ans;
186
+ for (auto& [ _ , v] : d) ans.emplace_back(v);
187
+ return ans;
125
188
}
189
+ };
190
+ ```
191
+
192
+ ```go
193
+ func groupAnagrams(strs []string) (ans [][]string) {
194
+ d := map[[26]int][]string{}
195
+ for _, s := range strs {
196
+ cnt := [26]int{}
197
+ for _, c := range s {
198
+ cnt[c-'a']++
199
+ }
200
+ d[cnt] = append(d[cnt], s)
201
+ }
202
+ for _, v := range d {
203
+ ans = append(ans, v)
204
+ }
205
+ return
126
206
}
127
207
```
128
208
0 commit comments