24
24
25
25
<!-- 这里可写通用的实现逻辑 -->
26
26
27
- 并查集。
27
+ ** 方法一:哈希表 + DFS**
28
+
29
+ 对于每个同义词对,我们将其两个名字建立双向边,存放在邻接表 $g$ 中,然后,我们遍历所有名字,将其存放在集合 $s$ 中,同时将其频率存放在哈希表 $cnt$ 中。
30
+
31
+ 接下来,我们遍历集合 $s$ 中的每个名字,如果该名字未被访问过,则进行深度优先搜索,找到该名字所在的连通分量中的所有名字,以字典序最小的名字为真实名字,将其频率求和,即为真实名字的频率。然后,我们将该名字以及其频率存放在答案数组中。
32
+
33
+ 遍历完所有名字后,答案数组即为所求。
34
+
35
+ 时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为名字数组和同义词数组的长度。
28
36
29
37
<!-- tabs:start -->
30
38
35
43
``` python
36
44
class Solution :
37
45
def trulyMostPopular (self , names : List[str ], synonyms : List[str ]) -> List[str ]:
38
- mp = defaultdict(int )
39
- p = defaultdict(str )
40
-
41
- def find (x ):
42
- if p[x] != x:
43
- p[x] = find(p[x])
44
- return p[x]
45
-
46
- def union (a , b ):
47
- pa, pb = find(a), find(b)
48
- if pa == pb:
49
- return
50
- if pa > pb:
51
- mp[pb] += mp[pa]
52
- p[pa] = pb
53
- else :
54
- mp[pa] += mp[pb]
55
- p[pb] = pa
56
-
57
- for e in names:
58
- idx = e.find(" (" )
59
- name, w = e[:idx], int (e[idx + 1 : - 1 ])
60
- mp[name] = w
61
- p[name] = name
62
- for e in synonyms:
63
- idx = e.find(" ," )
64
- name1, name2 = e[1 :idx], e[idx + 1 : - 1 ]
65
- mp[name1] += 0
66
- mp[name2] += 0
67
- p[name1] = name1
68
- p[name2] = name2
69
-
46
+ def dfs (a ):
47
+ vis.add(a)
48
+ mi, x = a, cnt[a]
49
+ for b in g[a]:
50
+ if b not in vis:
51
+ t, y = dfs(b)
52
+ if mi > t:
53
+ mi = t
54
+ x += y
55
+ return mi, x
56
+
57
+ g = defaultdict(list )
70
58
for e in synonyms:
71
- idx = e.find(" ," )
72
- name1, name2 = e[1 :idx], e[idx + 1 : - 1 ]
73
- union(name1, name2)
74
- return [f ' { name} ( { mp[name]} ) ' for name, w in mp.items() if name == find(name)]
59
+ a, b = e[1 :- 1 ].split(' ,' )
60
+ g[a].append(b)
61
+ g[b].append(a)
62
+ s = set ()
63
+ cnt = defaultdict(int )
64
+ for x in names:
65
+ name, freq = x[:- 1 ].split(" (" )
66
+ s.add(name)
67
+ cnt[name] = int (freq)
68
+ vis = set ()
69
+ ans = []
70
+ for name in s:
71
+ if name not in vis:
72
+ name, freq = dfs(name)
73
+ ans.append(f " { name} ( { freq} ) " )
74
+ return ans
75
75
```
76
76
77
77
### ** Java**
@@ -80,70 +80,151 @@ class Solution:
80
80
81
81
``` java
82
82
class Solution {
83
- private Map<String , Integer > mp = new HashMap<> ();
84
- private Map<String , String > p = new HashMap<> ();
83
+ private Map<String , List<String > > g = new HashMap<> ();
84
+ private Map<String , Integer > cnt = new HashMap<> ();
85
+ private Set<String > vis = new HashSet<> ();
86
+ private int freq;
85
87
86
88
public String [] trulyMostPopular (String [] names , String [] synonyms ) {
87
- for (String e : names) {
88
- int idx = e. indexOf(" (" );
89
- String name = e. substring(0 , idx);
90
- int w = Integer . parseInt(e. substring(idx + 1 , e. length() - 1 ));
91
- mp. put(name, w);
92
- p. put(name, name);
89
+ for (String pairs : synonyms) {
90
+ String [] pair = pairs. substring(1 , pairs. length() - 1 ). split(" ," );
91
+ String a = pair[0 ], b = pair[1 ];
92
+ g. computeIfAbsent(a, k - > new ArrayList<> ()). add(b);
93
+ g. computeIfAbsent(b, k - > new ArrayList<> ()). add(a);
93
94
}
94
- for (String e : synonyms) {
95
- int idx = e. indexOf(" ," );
96
- String name1 = e. substring(1 , idx);
97
- String name2 = e. substring(idx + 1 , e. length() - 1 );
98
- if (! mp. containsKey(name1)) {
99
- mp. put(name1, 0 );
100
- }
101
- if (! mp. containsKey(name2)) {
102
- mp. put(name2, 0 );
103
- }
104
- p. put(name1, name1);
105
- p. put(name2, name2);
95
+ Set<String > s = new HashSet<> ();
96
+ for (String x : names) {
97
+ int i = x. indexOf(' (' );
98
+ String name = x. substring(0 , i);
99
+ s. add(name);
100
+ cnt. put(name, Integer . parseInt(x. substring(i + 1 , x. length() - 1 )));
106
101
}
107
- for (String e : synonyms) {
108
- int idx = e. indexOf(" ," );
109
- String name1 = e. substring(1 , idx);
110
- String name2 = e. substring(idx + 1 , e. length() - 1 );
111
- union(name1, name2);
112
- }
113
- List<String > t = new ArrayList<> ();
114
- for (Map . Entry<String , Integer > e : mp. entrySet()) {
115
- String name = e. getKey();
116
- if (Objects . equals(name, find(name))) {
117
- t. add(name + " (" + e. getValue() + " )" );
102
+ List<String > res = new ArrayList<> ();
103
+ for (String name : s) {
104
+ if (! vis. contains(name)) {
105
+ freq = 0 ;
106
+ name = dfs(name);
107
+ res. add(name + " (" + freq + " )" );
118
108
}
119
109
}
120
- String [] res = new String [t. size()];
121
- for (int i = 0 ; i < res. length; ++ i) {
122
- res[i] = t. get(i);
123
- }
124
- return res;
110
+ return res. toArray(new String [0 ]);
125
111
}
126
112
127
- private String find (String x ) {
128
- if (! Objects . equals(p. get(x), x)) {
129
- p. put(x, find(p. get(x)));
113
+ private String dfs (String a ) {
114
+ String mi = a;
115
+ vis. add(a);
116
+ freq += cnt. getOrDefault(a, 0 );
117
+ for (String b : g. getOrDefault(a, new ArrayList<> ())) {
118
+ if (! vis. contains(b)) {
119
+ String t = dfs(b);
120
+ if (t. compareTo(mi) < 0 ) {
121
+ mi = t;
122
+ }
123
+ }
130
124
}
131
- return p . get(x) ;
125
+ return mi ;
132
126
}
127
+ }
128
+ ```
133
129
134
- private void union (String a , String b ) {
135
- String pa = find(a), pb = find(b);
136
- if (Objects . equals(pa, pb)) {
137
- return ;
130
+ ### ** C++**
131
+
132
+ ``` cpp
133
+ class Solution {
134
+ public:
135
+ vector<string > trulyMostPopular(vector<string >& names, vector<string >& synonyms) {
136
+ unordered_map<string, vector<string >> g;
137
+ unordered_map<string, int> cnt;
138
+ for (auto& e : synonyms) {
139
+ int i = e.find(',');
140
+ string a = e.substr(1, i - 1);
141
+ string b = e.substr(i + 1, e.size() - i - 2);
142
+ g[ a] .emplace_back(b);
143
+ g[ b] .emplace_back(a);
138
144
}
139
- if (pa . compareTo(pb) > 0 ) {
140
- mp . put(pb, mp . getOrDefault(pb, 0 ) + mp . getOrDefault(pa, 0 ));
141
- p . put(pa, pb );
142
- } else {
143
- mp . put(pa, mp . getOrDefault(pa, 0 ) + mp . getOrDefault(pb, 0 ) );
144
- p . put(pb, pa );
145
+ unordered_set< string > s;
146
+ for (auto& e : names) {
147
+ int i = e.find('(' );
148
+ string name = e.substr(0, i);
149
+ s.insert(name );
150
+ cnt [ name ] += stoi(e.substr(i + 1, e.size() - i - 2) );
145
151
}
152
+ unordered_set<string > vis;
153
+ int freq = 0;
154
+
155
+ function<string(string)> dfs = [&](string a) -> string {
156
+ string res = a;
157
+ vis.insert(a);
158
+ freq += cnt[a];
159
+ for (auto& b : g[a]) {
160
+ if (!vis.count(b)) {
161
+ string t = dfs(b);
162
+ if (t < res) {
163
+ res = move(t);
164
+ }
165
+ }
166
+ }
167
+ return move(res);
168
+ };
169
+
170
+ vector<string> ans;
171
+ for (auto & name : s) {
172
+ if (!vis.count(name)) {
173
+ freq = 0;
174
+ string x = dfs(name);
175
+ ans.emplace_back(x + "(" + to_string(freq) + ")");
176
+ }
177
+ }
178
+ return ans;
146
179
}
180
+ };
181
+ ```
182
+
183
+ ### ** Go**
184
+
185
+ ``` go
186
+ func trulyMostPopular (names []string , synonyms []string ) (ans []string ) {
187
+ g := map [string ][]string {}
188
+ for _ , s := range synonyms {
189
+ i := strings.Index (s, " ," )
190
+ a , b := s[1 :i], s[i+1 :len (s)-1 ]
191
+ g[a] = append (g[a], b)
192
+ g[b] = append (g[b], a)
193
+ }
194
+ s := map [string ]struct {}{}
195
+ cnt := map [string ]int {}
196
+ for _ , e := range names {
197
+ i := strings.Index (e, " (" )
198
+ name , num := e[:i], e[i+1 :len (e)-1 ]
199
+ x , _ := strconv.Atoi (num)
200
+ cnt[name] += x
201
+ s[name] = struct {}{}
202
+ }
203
+ freq := 0
204
+ vis := map [string ]struct {}{}
205
+ var dfs func (string ) string
206
+ dfs = func (a string ) string {
207
+ vis[a] = struct {}{}
208
+ freq += cnt[a]
209
+ res := a
210
+ for _ , b := range g[a] {
211
+ if _ , ok := vis[b]; !ok {
212
+ t := dfs (b)
213
+ if t < res {
214
+ res = t
215
+ }
216
+ }
217
+ }
218
+ return res
219
+ }
220
+ for name := range s {
221
+ if _ , ok := vis[name]; !ok {
222
+ freq = 0
223
+ root := dfs (name)
224
+ ans = append (ans, root+" (" +strconv.Itoa (freq)+" )" )
225
+ }
226
+ }
227
+ return
147
228
}
148
229
```
149
230
0 commit comments