Skip to content

Commit e664b42

Browse files
committed
feat: add solutions to lcci problem: No.17.07
No.17.07.Baby Names
1 parent 43f6de8 commit e664b42

File tree

7 files changed

+483
-266
lines changed

7 files changed

+483
-266
lines changed

lcci/17.05.Find Longest Subarray/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,12 +39,12 @@
3939

4040
我们可以运用前缀和的思想,用哈希表 $vis$ 记录每个前缀和第一次出现的位置,用变量 $mx$ 和 $k$ 分别记录最长的满足条件的子数组的长度和左端点位置。
4141

42-
遍历数组,计算当前位置 $i$ 的前缀和 $s$:
42+
接下来遍历数组,计算当前位置 $i$ 的前缀和 $s$:
4343

4444
- 如果当前位置的前缀和 $s$ 在哈希表 $vis$ 中存在,我们记第一次出现 $s$ 的位置为 $j$,那么区间 $[j + 1,..,i]$ 的子数组和就为 $0$。如果此前的最长子数组的长度小于当前子数组的长度,即 $mx \lt i - j$,我们就更新 $mx = i - j$ 和 $k = j + 1$。
4545
- 否则,我们将当前位置的前缀和 $s$ 作为键,当前位置 $i$ 作为值,存入哈希表 $vis$ 中。
4646

47-
遍历结束后,如果 $mx = 0$,说明不存在这样的子数组,返回空数组;否则,返回区间 $[k,..,k + mx - 1]$ 的子数组即可。
47+
遍历结束后,返回左端点为 $k$,且长度为 $mx$ 的子数组即可。
4848

4949
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
5050

lcci/17.07.Baby Names/README.md

+168-87
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,15 @@
2424

2525
<!-- 这里可写通用的实现逻辑 -->
2626

27-
并查集。
27+
**方法一:哈希表 + DFS**
28+
29+
对于每个同义词对,我们将其两个名字建立双向边,存放在邻接表 $g$ 中,然后,我们遍历所有名字,将其存放在集合 $s$ 中,同时将其频率存放在哈希表 $cnt$ 中。
30+
31+
接下来,我们遍历集合 $s$ 中的每个名字,如果该名字未被访问过,则进行深度优先搜索,找到该名字所在的连通分量中的所有名字,以字典序最小的名字为真实名字,将其频率求和,即为真实名字的频率。然后,我们将该名字以及其频率存放在答案数组中。
32+
33+
遍历完所有名字后,答案数组即为所求。
34+
35+
时间复杂度 $O(n + m)$,空间复杂度 $O(n + m)$。其中 $n$ 和 $m$ 分别为名字数组和同义词数组的长度。
2836

2937
<!-- tabs:start -->
3038

@@ -35,43 +43,35 @@
3543
```python
3644
class Solution:
3745
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)
7058
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
7575
```
7676

7777
### **Java**
@@ -80,70 +80,151 @@ class Solution:
8080

8181
```java
8282
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;
8587

8688
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);
9394
}
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)));
106101
}
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 + ")");
118108
}
119109
}
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]);
125111
}
126112

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+
}
130124
}
131-
return p.get(x);
125+
return mi;
132126
}
127+
}
128+
```
133129

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);
138144
}
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));
145151
}
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;
146179
}
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
147228
}
148229
```
149230

0 commit comments

Comments
 (0)