Skip to content

Commit 6948aff

Browse files
committed
feat: add solutions to lc problem: No.1733
No.1733.Minimum Number of People to Teach
1 parent 0651e16 commit 6948aff

File tree

9 files changed

+262
-50
lines changed

9 files changed

+262
-50
lines changed

solution/1700-1799/1733.Minimum Number of People to Teach/README.md

Lines changed: 89 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ tags:
7777

7878
对于每个好友关系,如果两个人掌握的语言集合不相交,则需要教一门语言,使得两个人可以相互沟通,我们将这些人放入一个哈希集合 $s$ 中。
7979

80-
然后在这个集合 $s$ 中,统计每种语言掌握的人数,获取最大的人数,我们记为 $mx$,那么答案就是 `len(s) - mx`
80+
然后在这个集合 $s$ 中,统计每种语言掌握的人数,获取最大的人数,我们记为 $mx$,那么答案就是 $|s| - mx$。其中 $|s|$ 表示集合 $s$ 的大小
8181

8282
时间复杂度 $O(m^2 \times k)$。其中 $m$ 为语言的数量,而 $k$ 为好友关系的数量。
8383

@@ -90,7 +90,7 @@ class Solution:
9090
def minimumTeachings(
9191
self, n: int, languages: List[List[int]], friendships: List[List[int]]
9292
) -> int:
93-
def check(u, v):
93+
def check(u: int, v: int) -> bool:
9494
for x in languages[u - 1]:
9595
for y in languages[v - 1]:
9696
if x == y:
@@ -158,9 +158,19 @@ class Solution {
158158
public:
159159
int minimumTeachings(int n, vector<vector<int>>& languages, vector<vector<int>>& friendships) {
160160
unordered_set<int> s;
161+
auto check = [&](int u, int v) {
162+
for (int x : languages[u - 1]) {
163+
for (int y : languages[v - 1]) {
164+
if (x == y) {
165+
return true;
166+
}
167+
}
168+
}
169+
return false;
170+
};
161171
for (auto& e : friendships) {
162172
int u = e[0], v = e[1];
163-
if (!check(u, v, languages)) {
173+
if (!check(u, v)) {
164174
s.insert(u);
165175
s.insert(v);
166176
}
@@ -174,18 +184,7 @@ public:
174184
++cnt[l];
175185
}
176186
}
177-
return s.size() - *max_element(cnt.begin(), cnt.end());
178-
}
179-
180-
bool check(int u, int v, vector<vector<int>>& languages) {
181-
for (int x : languages[u - 1]) {
182-
for (int y : languages[v - 1]) {
183-
if (x == y) {
184-
return true;
185-
}
186-
}
187-
}
188-
return false;
187+
return s.size() - ranges::max(cnt);
189188
}
190189
};
191190
```
@@ -224,6 +223,81 @@ func minimumTeachings(n int, languages [][]int, friendships [][]int) int {
224223
}
225224
```
226225

226+
#### TypeScript
227+
228+
```ts
229+
function minimumTeachings(n: number, languages: number[][], friendships: number[][]): number {
230+
function check(u: number, v: number): boolean {
231+
for (const x of languages[u - 1]) {
232+
for (const y of languages[v - 1]) {
233+
if (x === y) {
234+
return true;
235+
}
236+
}
237+
}
238+
return false;
239+
}
240+
241+
const s = new Set<number>();
242+
for (const [u, v] of friendships) {
243+
if (!check(u, v)) {
244+
s.add(u);
245+
s.add(v);
246+
}
247+
}
248+
249+
const cnt = new Map<number, number>();
250+
for (const u of s) {
251+
for (const l of languages[u - 1]) {
252+
cnt.set(l, (cnt.get(l) || 0) + 1);
253+
}
254+
}
255+
256+
return s.size - Math.max(0, ...cnt.values());
257+
}
258+
```
259+
260+
#### Rust
261+
262+
```rust
263+
use std::collections::{HashSet, HashMap};
264+
265+
impl Solution {
266+
pub fn minimum_teachings(n: i32, languages: Vec<Vec<i32>>, friendships: Vec<Vec<i32>>) -> i32 {
267+
fn check(u: usize, v: usize, languages: &Vec<Vec<i32>>) -> bool {
268+
for &x in &languages[u - 1] {
269+
for &y in &languages[v - 1] {
270+
if x == y {
271+
return true;
272+
}
273+
}
274+
}
275+
false
276+
}
277+
278+
let mut s: HashSet<usize> = HashSet::new();
279+
for edge in friendships.iter() {
280+
let u = edge[0] as usize;
281+
let v = edge[1] as usize;
282+
if !check(u, v, &languages) {
283+
s.insert(u);
284+
s.insert(v);
285+
}
286+
}
287+
288+
let mut cnt: HashMap<i32, i32> = HashMap::new();
289+
for &u in s.iter() {
290+
for &l in &languages[u - 1] {
291+
*cnt.entry(l).or_insert(0) += 1;
292+
}
293+
}
294+
295+
let mx = cnt.values().cloned().max().unwrap_or(0);
296+
(s.len() as i32) - mx
297+
}
298+
}
299+
```
300+
227301
<!-- tabs:end -->
228302

229303
<!-- solution:end -->

solution/1700-1799/1733.Minimum Number of People to Teach/README_EN.md

Lines changed: 90 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ Note that friendships are not transitive, meaning if <code>x</code> is a friend
7272

7373
### Solution 1: Simulation + Statistics
7474

75-
For each friendship, if the sets of languages known by the two people do not intersect, then a language needs to be taught so that the two people can communicate with each other. We put these people into a hash set $s$.
75+
For each friendship, if the sets of languages known by the two people do not intersect, we need to teach one language so that they can communicate. We add these people to a hash set $s$.
7676

77-
Then in this set $s$, we count the number of people who know each language, and get the maximum number, which we denote as $mx$. So the answer is `len(s) - mx`.
77+
Then, for each language, we count how many people in set $s$ know that language and find the maximum count, denoted as $mx$. The answer is $|s| - mx$, where $|s|$ is the size of set $s$.
7878

7979
The time complexity is $O(m^2 \times k)$. Here, $m$ is the number of languages, and $k$ is the number of friendships.
8080

@@ -87,7 +87,7 @@ class Solution:
8787
def minimumTeachings(
8888
self, n: int, languages: List[List[int]], friendships: List[List[int]]
8989
) -> int:
90-
def check(u, v):
90+
def check(u: int, v: int) -> bool:
9191
for x in languages[u - 1]:
9292
for y in languages[v - 1]:
9393
if x == y:
@@ -155,9 +155,19 @@ class Solution {
155155
public:
156156
int minimumTeachings(int n, vector<vector<int>>& languages, vector<vector<int>>& friendships) {
157157
unordered_set<int> s;
158+
auto check = [&](int u, int v) {
159+
for (int x : languages[u - 1]) {
160+
for (int y : languages[v - 1]) {
161+
if (x == y) {
162+
return true;
163+
}
164+
}
165+
}
166+
return false;
167+
};
158168
for (auto& e : friendships) {
159169
int u = e[0], v = e[1];
160-
if (!check(u, v, languages)) {
170+
if (!check(u, v)) {
161171
s.insert(u);
162172
s.insert(v);
163173
}
@@ -171,18 +181,7 @@ public:
171181
++cnt[l];
172182
}
173183
}
174-
return s.size() - *max_element(cnt.begin(), cnt.end());
175-
}
176-
177-
bool check(int u, int v, vector<vector<int>>& languages) {
178-
for (int x : languages[u - 1]) {
179-
for (int y : languages[v - 1]) {
180-
if (x == y) {
181-
return true;
182-
}
183-
}
184-
}
185-
return false;
184+
return s.size() - ranges::max(cnt);
186185
}
187186
};
188187
```
@@ -221,6 +220,81 @@ func minimumTeachings(n int, languages [][]int, friendships [][]int) int {
221220
}
222221
```
223222

223+
#### TypeScript
224+
225+
```ts
226+
function minimumTeachings(n: number, languages: number[][], friendships: number[][]): number {
227+
function check(u: number, v: number): boolean {
228+
for (const x of languages[u - 1]) {
229+
for (const y of languages[v - 1]) {
230+
if (x === y) {
231+
return true;
232+
}
233+
}
234+
}
235+
return false;
236+
}
237+
238+
const s = new Set<number>();
239+
for (const [u, v] of friendships) {
240+
if (!check(u, v)) {
241+
s.add(u);
242+
s.add(v);
243+
}
244+
}
245+
246+
const cnt = new Map<number, number>();
247+
for (const u of s) {
248+
for (const l of languages[u - 1]) {
249+
cnt.set(l, (cnt.get(l) || 0) + 1);
250+
}
251+
}
252+
253+
return s.size - Math.max(0, ...cnt.values());
254+
}
255+
```
256+
257+
#### Rust
258+
259+
```rust
260+
use std::collections::{HashSet, HashMap};
261+
262+
impl Solution {
263+
pub fn minimum_teachings(n: i32, languages: Vec<Vec<i32>>, friendships: Vec<Vec<i32>>) -> i32 {
264+
fn check(u: usize, v: usize, languages: &Vec<Vec<i32>>) -> bool {
265+
for &x in &languages[u - 1] {
266+
for &y in &languages[v - 1] {
267+
if x == y {
268+
return true;
269+
}
270+
}
271+
}
272+
false
273+
}
274+
275+
let mut s: HashSet<usize> = HashSet::new();
276+
for edge in friendships.iter() {
277+
let u = edge[0] as usize;
278+
let v = edge[1] as usize;
279+
if !check(u, v, &languages) {
280+
s.insert(u);
281+
s.insert(v);
282+
}
283+
}
284+
285+
let mut cnt: HashMap<i32, i32> = HashMap::new();
286+
for &u in s.iter() {
287+
for &l in &languages[u - 1] {
288+
*cnt.entry(l).or_insert(0) += 1;
289+
}
290+
}
291+
292+
let mx = cnt.values().cloned().max().unwrap_or(0);
293+
(s.len() as i32) - mx
294+
}
295+
}
296+
```
297+
224298
<!-- tabs:end -->
225299

226300
<!-- solution:end -->

solution/1700-1799/1733.Minimum Number of People to Teach/Solution.cpp

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,19 @@ class Solution {
22
public:
33
int minimumTeachings(int n, vector<vector<int>>& languages, vector<vector<int>>& friendships) {
44
unordered_set<int> s;
5+
auto check = [&](int u, int v) {
6+
for (int x : languages[u - 1]) {
7+
for (int y : languages[v - 1]) {
8+
if (x == y) {
9+
return true;
10+
}
11+
}
12+
}
13+
return false;
14+
};
515
for (auto& e : friendships) {
616
int u = e[0], v = e[1];
7-
if (!check(u, v, languages)) {
17+
if (!check(u, v)) {
818
s.insert(u);
919
s.insert(v);
1020
}
@@ -18,17 +28,6 @@ class Solution {
1828
++cnt[l];
1929
}
2030
}
21-
return s.size() - *max_element(cnt.begin(), cnt.end());
22-
}
23-
24-
bool check(int u, int v, vector<vector<int>>& languages) {
25-
for (int x : languages[u - 1]) {
26-
for (int y : languages[v - 1]) {
27-
if (x == y) {
28-
return true;
29-
}
30-
}
31-
}
32-
return false;
31+
return s.size() - ranges::max(cnt);
3332
}
34-
};
33+
};

solution/1700-1799/1733.Minimum Number of People to Teach/Solution.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ class Solution:
22
def minimumTeachings(
33
self, n: int, languages: List[List[int]], friendships: List[List[int]]
44
) -> int:
5-
def check(u, v):
5+
def check(u: int, v: int) -> bool:
66
for x in languages[u - 1]:
77
for y in languages[v - 1]:
88
if x == y:
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
use std::collections::{HashMap, HashSet};
2+
3+
impl Solution {
4+
pub fn minimum_teachings(n: i32, languages: Vec<Vec<i32>>, friendships: Vec<Vec<i32>>) -> i32 {
5+
fn check(u: usize, v: usize, languages: &Vec<Vec<i32>>) -> bool {
6+
for &x in &languages[u - 1] {
7+
for &y in &languages[v - 1] {
8+
if x == y {
9+
return true;
10+
}
11+
}
12+
}
13+
false
14+
}
15+
16+
let mut s: HashSet<usize> = HashSet::new();
17+
for edge in friendships.iter() {
18+
let u = edge[0] as usize;
19+
let v = edge[1] as usize;
20+
if !check(u, v, &languages) {
21+
s.insert(u);
22+
s.insert(v);
23+
}
24+
}
25+
26+
let mut cnt: HashMap<i32, i32> = HashMap::new();
27+
for &u in s.iter() {
28+
for &l in &languages[u - 1] {
29+
*cnt.entry(l).or_insert(0) += 1;
30+
}
31+
}
32+
33+
let mx = cnt.values().cloned().max().unwrap_or(0);
34+
(s.len() as i32) - mx
35+
}
36+
}

0 commit comments

Comments
 (0)