On a social network consisting of m users and some friendships between users, two users can communicate with each other if they know a common language.
You are given an integer n, an array languages, and an array friendships where:
n languages numbered 1 through n,languages[i] is the set of languages the ith user knows, andfriendships[i] = [ui, vi] denotes a friendship between the users ui and vi.You can choose one language and teach it to some users so that all friends can communicate with each other. Return the minimum number of users you need to teach.
Note that friendships are not transitive, meaning ifx is a friend of y and y is a friend of z, this doesn't guarantee that x is a friend of z.
Example 1:
Input: n = 2, languages = [[1],[2],[1,2]], friendships = [[1,2],[1,3],[2,3]] Output: 1 Explanation: You can either teach user 1 the second language or user 2 the first language.
Example 2:
Input: n = 3, languages = [[2],[1,3],[1,2],[3]], friendships = [[1,4],[1,2],[3,4],[2,3]] Output: 2 Explanation: Teach the third language to users 1 and 3, yielding two users to teach.
Constraints:
2 <= n <= 500languages.length == m1 <= m <= 5001 <= languages[i].length <= n1 <= languages[i][j] <= n1 <= ui < vi <= languages.length1 <= friendships.length <= 500(ui, vi) are uniquelanguages[i] contains only unique valuesWhen you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The brute force way to solve this problem is like trying every single combination of people to teach until we find one that makes sure everyone can communicate. We will painstakingly explore each possibility to guarantee we find the absolute minimum.
Here's how the algorithm would work step-by-step:
def minimum_people_to_teach(number_of_people, languages):
minimum_people_needed = number_of_people
for i in range(1 << number_of_people):
people_to_teach = []
number_of_people_to_teach = 0
for person_index in range(number_of_people):
if (i >> person_index) & 1:
people_to_teach.append(person_index)
number_of_people_to_teach += 1
# Create a copy to avoid modifying the original list
updated_languages = [set(lang) for lang in languages]
for person_index in people_to_teach:
updated_languages[person_index].add(0)
can_communicate = True
for first_person in range(number_of_people):
can_talk_to_someone = False
for second_person in range(number_of_people):
# Check if the people speak a common language
if len(updated_languages[first_person].intersection(updated_languages[second_person])) > 0:
can_talk_to_someone = True
break
if not can_talk_to_someone:
can_communicate = False
break
# Update if this combination results in fewer people taught
if can_communicate:
minimum_people_needed = min(minimum_people_needed, number_of_people_to_teach)
return minimum_people_needed
The problem asks us to minimize the number of people we need to teach a new set of languages to, so that everyone in a social network can understand each other. The key is to find which languages are not already understood by everyone directly or indirectly connected to each other. Then we teach those languages to someone already in the social network.
Here's how the algorithm would work step-by-step:
def minimum_teachings(number_of_people, languages):
social_network = [set() for _ in range(number_of_people)]
for person1 in range(number_of_people):
for person2 in range(person1 + 1, number_of_people):
if any(language in languages[person2] for language in languages[person1]):
social_network[person1].add(person2)
social_network[person2].add(person1)
visited = [False] * number_of_people
connected_components = []
def depth_first_search(person, component):
visited[person] = True
component.add(person)
for neighbor in social_network[person]:
if not visited[neighbor]:
depth_first_search(neighbor, component)
# Build social network map with DFS
for person in range(number_of_people):
if not visited[person]:
component = set()
depth_first_search(person, component)
connected_components.append(component)
people_to_teach_count = 0
for component in connected_components:
shared_language = False
if len(component) == 1:
continue
component_languages = set()
people_in_component = list(component)
# Collect all languages spoken in the component
for person in people_in_component:
component_languages.update(languages[person])
# Check if everyone already shares a language
for language in component_languages:
language_is_shared = True
for person in people_in_component:
if language not in languages[person]:
language_is_shared = False
break
if language_is_shared:
shared_language = True
break
# Increment count if shared language is absent
if not shared_language:
people_to_teach_count += 1
return people_to_teach_count| Case | How to Handle |
|---|---|
| n = 0, empty languages, empty friendships | Return 0, as there are no people or friendships to satisfy. |
| n = 1, languages contains one language, friendships empty | Return 0, as there's only one person and no friendships to satisfy. |
| n = 2, friendship exists, but languages are empty for both | Return 2, as both need to be taught a language to communicate. |
| n = 2, friendship exists, one person knows a language, other knows none | Return 1, the person who knows no language needs to be taught. |
| n = 2, friendship exists, both know completely disjoint languages | Return 1; teach either person a language the other knows, or teach a common language. |
| Large n, but all friendships connect into a single connected component, and no one shares a language. | Return 1; teaching everyone the same language will solve the problem; connected components can be found using DFS/BFS/Union-Find. |
| Friendships form multiple disconnected components; languages may or may not overlap within or between components. | Calculate the minimum number of people to teach within each component and sum the results; use DFS/BFS/Union-Find to find components. |
| All people already speak a common language, but friendships still exist. | Return 0, as all friendships are already satisfied. |