奖励最顶尖的 K 名学生【LC2512】
给你两个字符串数组
positive_feedback
和negative_feedback
,分别包含表示正面的和负面的词汇。不会 有单词同时是正面的和负面的。一开始,每位学生分数为
0
。每个正面的单词会给学生的分数 加3
分,每个负面的词会给学生的分数 减1
分。给你
n
个学生的评语,用一个下标从 0 开始的字符串数组report
和一个下标从 0 开始的整数数组student_id
表示,其中student_id[i]
表示这名学生的 ID ,这名学生的评语是report[i]
。每名学生的 ID 互不相同。给你一个整数
k
,请你返回按照得分 从高到低 最顶尖的k
名学生。如果有多名学生分数相同,ID 越小排名越前。
-
思路
- 使用两个哈希表分别存储正面单词以及负面单词
- 然后遍历每个学生的评语,逐个判断是否是正面单词或者负面单词,求出每个学生的分数
- 对分数进行升序排序,分数相等时,ID 越小排名越前
- 最后取前 k k k个学生的ID
-
实现
class Solution { public List<Integer> topStudents(String[] positive_feedback, String[] negative_feedback, String[] report, int[] student_id, int k) { Set<String> pos = new HashSet<>(); Set<String> neg = new HashSet<>(); int n = report.length; int[][] score = new int[n][2]; for (String s : positive_feedback){ pos.add(s); } for (String s : negative_feedback){ neg.add(s); } for(int i = 0; i < n; i++){ String[] ss = report[i].split(" "); score[i][1] = student_id[i];// id for (String s : ss){ if (pos.contains(s)){ score[i][0] += 3; }else if (neg.contains(s)){ score[i][0] -= 1; } } } Arrays.sort(score, (o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]); List<Integer> res = new ArrayList<>(); for (int i = 0; i < k; i++){ res.add(score[i][1]); } return res; } }
- 复杂度
- 时间复杂度: O ( n log n + ( ∣ p o s ∣ + ∣ n e g ∣ + n ) ∗ ∣ s ∣ ) O(n \log n +(|pos|+|neg|+n)*|s|) O(nlogn+(∣pos∣+∣neg∣+n)∗∣s∣),其中 n n n为学生数量, ∣ p o s ∣ |pos| ∣pos∣ 和 ∣ n e g ∣ |neg| ∣neg∣ 分别为正面和负面单词的数量, ∣ s ∣ |s| ∣s∣为单词的平均长度
- 空间复杂度: O ( ( ∣ p o s ∣ + ∣ n e g ∣ ) ∗ ∣ s ∣ + n ) O((|pos|+|neg|)*|s|+n) O((∣pos∣+∣neg∣)∗∣s∣+n)
- 复杂度