返回介绍

solution / 2500-2599 / 2512.Reward Top K Students / README

发布于 2024-06-17 01:03:04 字数 8832 浏览 0 评论 0 收藏 0

2512. 奖励最顶尖的 K 名学生

English Version

题目描述

给你两个字符串数组 positive_feedback 和 negative_feedback ,分别包含表示正面的和负面的词汇。不会 有单词同时是正面的和负面的。

一开始,每位学生分数为 0 。每个正面的单词会给学生的分数 加 3 分,每个负面的词会给学生的分数 减  1 分。

给你 n 个学生的评语,用一个下标从 0 开始的字符串数组 report 和一个下标从 0 开始的整数数组 student_id 表示,其中 student_id[i] 表示这名学生的 ID ,这名学生的评语是 report[i] 。每名学生的 ID 互不相同

给你一个整数 k ,请你返回按照得分 从高到低 最顶尖的_ _k 名学生。如果有多名学生分数相同,ID 越小排名越前。

 

示例 1:

输入:positive_feedback = ["smart","brilliant","studious"], negative_feedback = ["not"], report = ["this student is studious","the student is smart"], student_id = [1,2], k = 2
输出:[1,2]
解释:
两名学生都有 1 个正面词汇,都得到 3 分,学生 1 的 ID 更小所以排名更前。

示例 2:

输入:positive_feedback = ["smart","brilliant","studious"], negative_feedback = ["not"], report = ["this student is not studious","the student is smart"], student_id = [1,2], k = 2
输出:[2,1]
解释:
- ID 为 1 的学生有 1 个正面词汇和 1 个负面词汇,所以得分为 3-1=2 分。
- ID 为 2 的学生有 1 个正面词汇,得分为 3 分。
学生 2 分数更高,所以返回 [2,1] 。

 

提示:

  • 1 <= positive_feedback.length, negative_feedback.length <= 104
  • 1 <= positive_feedback[i].length, negative_feedback[j].length <= 100
  • positive_feedback[i] 和 negative_feedback[j] 都只包含小写英文字母。
  • positive_feedback 和 negative_feedback 中不会有相同单词。
  • n == report.length == student_id.length
  • 1 <= n <= 104
  • report[i] 只包含小写英文字母和空格 ' ' 。
  • report[i] 中连续单词之间有单个空格隔开。
  • 1 <= report[i].length <= 100
  • 1 <= student_id[i] <= 109
  • student_id[i] 的值 互不相同 。
  • 1 <= k <= n

解法

方法一:哈希表 + 排序

我们可以将正面的单词存入哈希表 $ps$ 中,将负面的单词存入哈希表 $ns$ 中。

然后遍历 $report$,对于每个学生,我们将其得分存入数组 $arr$ 中,数组中的每个元素为一个二元组 $(t, sid)$,其中 $t$ 表示学生的得分,而 $sid$ 表示学生的 ID。

最后我们对数组 $arr$ 按照得分从高到低排序,如果得分相同则按照 ID 从小到大排序,然后取出前 $k$ 个学生的 ID 即可。

时间复杂度 $O(n \times \log n + (|ps| + |ns| + n) \times |s|)$,空间复杂度 $O((|ps|+|ns|) \times |s| + n)$。其中 $n$ 为学生数量,$|ps|$ 和 $|ns|$ 分别为正面和负面单词的数量,$|s|$ 为单词的平均长度。

class Solution:
  def topStudents(
    self,
    positive_feedback: List[str],
    negative_feedback: List[str],
    report: List[str],
    student_id: List[int],
    k: int,
  ) -> List[int]:
    ps = set(positive_feedback)
    ns = set(negative_feedback)
    arr = []
    for sid, r in zip(student_id, report):
      t = 0
      for w in r.split():
        if w in ps:
          t += 3
        elif w in ns:
          t -= 1
      arr.append((t, sid))
    arr.sort(key=lambda x: (-x[0], x[1]))
    return [v[1] for v in arr[:k]]
class Solution {
  public List<Integer> topStudents(String[] positive_feedback, String[] negative_feedback,
    String[] report, int[] student_id, int k) {
    Set<String> ps = new HashSet<>();
    Set<String> ns = new HashSet<>();
    for (var s : positive_feedback) {
      ps.add(s);
    }
    for (var s : negative_feedback) {
      ns.add(s);
    }
    int n = report.length;
    int[][] arr = new int[n][0];
    for (int i = 0; i < n; ++i) {
      int sid = student_id[i];
      int t = 0;
      for (var s : report[i].split(" ")) {
        if (ps.contains(s)) {
          t += 3;
        } else if (ns.contains(s)) {
          t -= 1;
        }
      }
      arr[i] = new int[] {t, sid};
    }
    Arrays.sort(arr, (a, b) -> a[0] == b[0] ? a[1] - b[1] : b[0] - a[0]);
    List<Integer> ans = new ArrayList<>();
    for (int i = 0; i < k; ++i) {
      ans.add(arr[i][1]);
    }
    return ans;
  }
}
class Solution {
public:
  vector<int> topStudents(vector<string>& positive_feedback, vector<string>& negative_feedback, vector<string>& report, vector<int>& student_id, int k) {
    unordered_set<string> ps(positive_feedback.begin(), positive_feedback.end());
    unordered_set<string> ns(negative_feedback.begin(), negative_feedback.end());
    vector<pair<int, int>> arr;
    int n = report.size();
    for (int i = 0; i < n; ++i) {
      int sid = student_id[i];
      vector<string> ws = split(report[i], ' ');
      int t = 0;
      for (auto& w : ws) {
        if (ps.count(w)) {
          t += 3;
        } else if (ns.count(w)) {
          t -= 1;
        }
      }
      arr.push_back({-t, sid});
    }
    sort(arr.begin(), arr.end());
    vector<int> ans;
    for (int i = 0; i < k; ++i) {
      ans.emplace_back(arr[i].second);
    }
    return ans;
  }

  vector<string> split(string& s, char delim) {
    stringstream ss(s);
    string item;
    vector<string> res;
    while (getline(ss, item, delim)) {
      res.emplace_back(item);
    }
    return res;
  }
};
func topStudents(positive_feedback []string, negative_feedback []string, report []string, student_id []int, k int) (ans []int) {
  ps := map[string]bool{}
  ns := map[string]bool{}
  for _, s := range positive_feedback {
    ps[s] = true
  }
  for _, s := range negative_feedback {
    ns[s] = true
  }
  arr := [][2]int{}
  for i, sid := range student_id {
    t := 0
    for _, w := range strings.Split(report[i], " ") {
      if ps[w] {
        t += 3
      } else if ns[w] {
        t -= 1
      }
    }
    arr = append(arr, [2]int{t, sid})
  }
  sort.Slice(arr, func(i, j int) bool { return arr[i][0] > arr[j][0] || (arr[i][0] == arr[j][0] && arr[i][1] < arr[j][1]) })
  for _, v := range arr[:k] {
    ans = append(ans, v[1])
  }
  return
}
function topStudents(
  positive_feedback: string[],
  negative_feedback: string[],
  report: string[],
  student_id: number[],
  k: number,
): number[] {
  const n = student_id.length;
  const map = new Map<number, number>();
  const ps = new Set(positive_feedback);
  const ns = new Set(negative_feedback);
  for (let i = 0; i < n; i++) {
    map.set(
      student_id[i],
      report[i].split(' ').reduce((r, s) => {
        if (ps.has(s)) {
          return r + 3;
        }
        if (ns.has(s)) {
          return r - 1;
        }
        return r;
      }, 0),
    );
  }
  return [...map.entries()]
    .sort((a, b) => {
      if (a[1] === b[1]) {
        return a[0] - b[0];
      }
      return b[1] - a[1];
    })
    .map(v => v[0])
    .slice(0, k);
}
use std::collections::{ HashMap, HashSet };
impl Solution {
  pub fn top_students(
    positive_feedback: Vec<String>,
    negative_feedback: Vec<String>,
    report: Vec<String>,
    student_id: Vec<i32>,
    k: i32
  ) -> Vec<i32> {
    let n = student_id.len();
    let ps = positive_feedback.iter().collect::<HashSet<&String>>();
    let ns = negative_feedback.iter().collect::<HashSet<&String>>();
    let mut map = HashMap::new();
    for i in 0..n {
      let id = student_id[i];
      let mut count = 0;
      for s in report[i].split(' ') {
        let s = &s.to_string();
        if ps.contains(s) {
          count += 3;
        } else if ns.contains(s) {
          count -= 1;
        }
      }
      map.insert(id, count);
    }
    let mut t = map.into_iter().collect::<Vec<(i32, i32)>>();
    t.sort_by(|a, b| {
      if a.1 == b.1 {
        return a.0.cmp(&b.0);
      }
      b.1.cmp(&a.1)
    });
    t.iter()
      .map(|v| v.0)
      .collect::<Vec<i32>>()
      [0..k as usize].to_vec()
  }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文