LeetCode in Kotlin

2512. Reward Top K Students

Medium

You are given two string arrays positive_feedback and negative_feedback, containing the words denoting positive and negative feedback, respectively. Note that no word is both positive and negative.

Initially every student has 0 points. Each positive word in a feedback report increases the points of a student by 3, whereas each negative word decreases the points by 1.

You are given n feedback reports, represented by a 0-indexed string array report and a 0-indexed integer array student_id, where student_id[i] represents the ID of the student who has received the feedback report report[i]. The ID of each student is unique.

Given an integer k, return the top k students after ranking them in non-increasing order by their points. In case more than one student has the same points, the one with the lower ID ranks higher.

Example 1:

Input: positive_feedback = [“smart”,”brilliant”,”studious”], negative_feedback = [“not”], report = [“this student is studious”,”the student is smart”], student_id = [1,2], k = 2

Output: [1,2]

Explanation: Both the students have 1 positive feedback and 3 points but since student 1 has a lower ID he ranks higher.

Example 2:

Input: positive_feedback = [“smart”,”brilliant”,”studious”], negative_feedback = [“not”], report = [“this student is not studious”,”the student is smart”], student_id = [1,2], k = 2

Output: [2,1]

Explanation:

Constraints:

Solution

import java.util.PriorityQueue

@Suppress("NAME_SHADOWING")
class Solution {
    fun topStudents(
        positiveFeedback: Array<String>,
        negativeFeedback: Array<String>,
        report: Array<String>,
        studentId: IntArray,
        k: Int,
    ): List<Int> {
        var k = k
        val feedback = HashMap<String, Int>()
        for (s in positiveFeedback) {
            feedback[s] = 3
        }
        for (s in negativeFeedback) {
            feedback[s] = -1
        }
        val pq = PriorityQueue { a: Student, b: Student ->
            val result = Integer.compare(a.points, b.points)
            if (result == 0) Integer.compare(a.id, b.id) else -result
        }
        for (i in report.indices) {
            val split = report[i].split(" ".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
            var sum = 0
            for (subStr in split) {
                sum += feedback.getOrDefault(subStr, 0)
            }
            pq.offer(Student(studentId[i], sum))
        }
        val result: MutableList<Int> = ArrayList()
        while (pq.isNotEmpty() && k-- > 0) {
            result.add(pq.poll().id)
        }
        return result
    }

    private class Student(var id: Int, var points: Int)
}