贪心题目:需要教语言的最少人数

文章目录

题目

标题和出处

标题:需要教语言的最少人数

出处:1733. 需要教语言的最少人数

难度

5 级

题目描述

要求

在一个由 m \texttt{m} m 个用户组成的社交网络中,有一些用户之间的好友关系。两个用户之间可以相互沟通的条件是他们都掌握同一门语言。

给定整数 n \texttt{n} n、数组 languages \texttt{languages} languages 和数组 friendships \texttt{friendships} friendships,它们的含义如下:

  • 总共有 n \texttt{n} n 种语言,编号从 1 \texttt{1} 1 到 n \texttt{n} n。
  • languagesi \texttt{languagesi} languagesi 是第 i \texttt{i} i 名用户掌握的语言集合。
  • friendshipsi = u i , v i \texttt{friendshipsi = u}_\\texttt{i}\\texttt{, v}_\\texttt{i}\\texttt{} friendshipsi = ui, vi 表示 u i \texttt{u}\texttt{i} ui 和 v i \texttt{v}\texttt{i} vi 为好友关系。

可以选择一门 语言并教会一些用户,使得所有好友之间都可以相互沟通。请返回最少需要教会多少名用户。

请注意,好友关系没有传递性,如果 x \texttt{x} x 和 y \texttt{y} y 是好友且 y \texttt{y} y 和 z \texttt{z} z 是好友, x \texttt{x} x 和 z \texttt{z} z 不一定是好友。

示例

示例 1:

输入: n = 2, languages = \[1,2,1,2], friendships = \[1,2,1,3,2,3] \texttt{n = 2, languages = \[1,2,1,2], friendships = \[1,2,1,3,2,3]} n = 2, languages = \[1,2,1,2], friendships = \[1,2,1,3,2,3]

输出: 1 \texttt{1} 1

解释:可以选择教用户 1 \texttt{1} 1 第二门语言,或选择教用户 2 \texttt{2} 2 第一门语言。

示例 2:

输入: n = 3, languages = \[2,1,3,1,2,3], friendships = \[1,4,1,2,3,4,2,3] \texttt{n = 3, languages = \[2,1,3,1,2,3], friendships = \[1,4,1,2,3,4,2,3]} n = 3, languages = \[2,1,3,1,2,3], friendships = \[1,4,1,2,3,4,2,3]

输出: 2 \texttt{2} 2

解释:教用户 1 \texttt{1} 1 和用户 3 \texttt{3} 3 第三门语言,需要教 2 \texttt{2} 2 名用户。

数据范围

  • 2 ≤ n ≤ 500 \texttt{2} \le \texttt{n} \le \texttt{500} 2≤n≤500
  • languages.length = m \texttt{languages.length} = \texttt{m} languages.length=m
  • 1 ≤ m ≤ 500 \texttt{1} \le \texttt{m} \le \texttt{500} 1≤m≤500
  • 1 ≤ languagesi.length ≤ n \texttt{1} \le \texttt{languagesi.length} \le \texttt{n} 1≤languagesi.length≤n
  • 1 ≤ languagesij ≤ n \texttt{1} \le \texttt{languagesij} \le \texttt{n} 1≤languagesij≤n
  • 1 ≤ u i < v i ≤ m \texttt{1} \le \texttt{u}\texttt{i} < \texttt{v}\texttt{i} \le \texttt{m} 1≤ui<vi≤m
  • 1 ≤ friendships.length ≤ 500 \texttt{1} \le \texttt{friendships.length} \le \texttt{500} 1≤friendships.length≤500
  • 所有的好友关系 (u i , v i ) \texttt{(u}\texttt{i}\texttt{, v}\texttt{i}\texttt{)} (ui, vi) 各不相同
  • languagesi \texttt{languagesi} languagesi 中包含的值各不相同

解法

思路和算法

为了使教语言的人数最少,应遵循如下贪心策略。

  1. 只有当一对好友没有共同掌握的语言时,才需要教其中至少一个用户一种语言。

  2. 对于上述用户,应选择这些用户中的掌握人数最多的语言,把该语言教给未掌握该语言的用户,则可满足上述用户都能掌握同一门语言且教语言的人数最少。

如果减少教语言的人数,则一定不能使上述用户都掌握同一种语言,也不能使所有的好友之间可以沟通,因此使用贪心策略可以得到需要教语言的最少人数。

具体做法如下。

  1. 遍历数组 languages \textit{languages} languages 记录每个用户掌握的所有语言。

  2. 遍历数组 friendships \textit{friendships} friendships 判断每一对好友是否有共同掌握的语言,使用哈希集合存储存在好友没有共同掌握的语言的用户。如果一对好友没有共同掌握的语言,则将这对好友的两个用户都加入哈希集合。

  3. 对于每种语言统计哈希集合中的未掌握该语言的人数,其中的最少人数即为需要教语言的最少人数。

实现方面,由于数组 languages \textit{languages} languages 中的语言编号和数组 friendships \textit{friendships} friendships 中的用户编号都是从 1 1 1 开始的编号,为了方便处理,需要将语言编号和用户编号都转换成从 0 0 0 开始的编号。

代码

java 复制代码
class Solution {
    public int minimumTeachings(int n, int[][] languages, int[][] friendships) {
        int m = languages.length;
        boolean[][] usersLanguages = new boolean[m][n];
        for (int i = 0; i < m; i++) {
            for (int j : languages[i]) {
                usersLanguages[i][j - 1] = true;
            }
        }
        Set<Integer> uncommon = new HashSet<Integer>();
        for (int[] friendship : friendships) {
            int u = friendship[0] - 1, v = friendship[1] - 1;
            boolean hasCommon = false;
            for (int j = 0; j < n && !hasCommon; j++) {
                if (usersLanguages[u][j] && usersLanguages[v][j]) {
                    hasCommon = true;
                }
            }
            if (!hasCommon) {
                uncommon.add(u);
                uncommon.add(v);
            }
        }
        int[] counts = new int[n];
        for (int i : uncommon) {
            for (int j = 0; j < n; j++) {
                if (!usersLanguages[i][j]) {
                    counts[j]++;
                }
            }
        }
        return Arrays.stream(counts).min().getAsInt();
    }
}

复杂度分析

  • 时间复杂度: O ( m n + p n ) O(mn + pn) O(mn+pn),其中 m m m 是用户的数量, n n n 是语言的数量, p p p 是好友关系的数量。遍历数组 languages \textit{languages} languages 记录每个用户掌握的所有语言的时间是 O ( m n ) O(mn) O(mn),遍历数组 friendships \textit{friendships} friendships 判断每一对好友是否有共同掌握的语言并使用哈希集合存储用户的时间是 O ( p n ) O(pn) O(pn),对于每种语言统计哈希集合中的未掌握该语言的人数的时间是 O ( m n ) O(mn) O(mn),因此时间复杂度是 O ( m n + p n ) O(mn + pn) O(mn+pn)。

  • 空间复杂度: O ( m n ) O(mn) O(mn),其中 m m m 是用户的数量, n n n 是语言的数量。记录每个用户掌握的所有语言的空间是 O ( m n ) O(mn) O(mn),哈希集合的空间是 O ( m ) O(m) O(m),统计每种语言的未掌握人数的空间是 O ( n ) O(n) O(n),因此空间复杂度是 O ( m n ) O(mn) O(mn)。

相关推荐
lvwangshu21 小时前
T3 涂鸦带师 题解
题解·贪心·倍增·技巧·思维好题·断环成链
吞下星星的少年·-·3 天前
牛客周赛 119B题(贪心)
算法·贪心
吞下星星的少年·-·4 天前
Div.2 CF edu195A题(数学,贪心)
数学·算法·贪心
伟大的车尔尼5 天前
贪心题目:交换一次的先前排列
贪心
lvwangshu6 天前
CF1882D Tree XOR 题解
动态规划·题解·贪心·dp·树形dp·换根dp·性质题·思维好题·推导题
伟大的车尔尼7 天前
贪心题目:救生艇
贪心
Jasmine_llq7 天前
《P8816 [CSP-J 2022] 上升点列》
数据结构·算法·贪心·排序·二维动态规划 dp·类背包状态转移
lvwangshu8 天前
字符串 题解
字符串·trie·题解·贪心·技巧·性质题·思维好题
Tisfy13 天前
LeetCode 2333.最小差值平方和:排序 + 数学计算(不用二分)
数学·算法·leetcode·题解·贪心·排序