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: - The student with ID 1 has 1 positive feedback and 1 negative feedback, so he has 3-1=2 points. - The student with ID 2 has 1 positive feedback, so he has 3 points. Since student 2 has more points, [2,1] is returned.
Constraints:
1 <= positive_feedback.length, negative_feedback.length <= 104
1 <= positive_feedback[i].length, negative_feedback[j].length <= 100
positive_feedback[i]
and negative_feedback[j]
consists of lowercase English letters.positive_feedback
and negative_feedback
.n == report.length == student_id.length
1 <= n <= 104
report[i]
consists of lowercase English letters and spaces ' '
.report[i]
.1 <= report[i].length <= 100
1 <= student_id[i] <= 109
student_id[i]
are unique.1 <= k <= n
When 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 approach to finding the top students is like checking every single student individually. We will calculate a score for each student based on the positive and negative feedback words and then compare everyone's score to find the top ones.
Here's how the algorithm would work step-by-step:
def reward_top_k_students_brute_force(positive_feedback, negative_feedback, student_reports, k_students):
student_scores = []
for report in student_reports:
score = 0
words = report.split()
for word in words:
if word in positive_feedback:
# Increment score for positive feedback
score += 1
if word in negative_feedback:
# Decrement score for negative feedback
score -= 1
student_scores.append(score)
# Create a list of (student_id, score) pairs
student_ids_with_scores = list(enumerate(student_scores))
# Sort students based on their scores in descending order
student_ids_with_scores.sort(key=lambda x: x[1], reverse=True)
# Extract the student IDs of the top K students
top_k_students = [student_id for student_id, score in student_ids_with_scores[:k_students]]
return top_k_students
To efficiently find the top students, we'll use a system to quickly rank them based on positive and negative feedback. The goal is to avoid comparing every single student directly to each other, saving a lot of time.
Here's how the algorithm would work step-by-step:
import heapq
def reward_top_k_students(student_ids, student_reports, positive_feedback, negative_feedback, k):
positive_words = set(positive_feedback)
negative_words = set(negative_feedback)
student_scores = {}
for index, student_id in enumerate(student_ids):
student_scores[student_id] = 0
report_words = student_reports[index].split()
for word in report_words:
if word in positive_words:
student_scores[student_id] += 3
elif word in negative_words:
student_scores[student_id] -= 1
# Use a min-heap to keep track of the top K students by score
top_k_heap = []
for student_id, score in student_scores.items():
heapq.heappush(top_k_heap, (score, student_id))
# Only keep the k highest scoring students
if len(top_k_heap) > k:
heapq.heappop(top_k_heap)
# Extract student IDs from the heap and reverse for descending order
top_k_students = [student_id for score, student_id in sorted(top_k_heap, reverse=True)]
return top_k_students
Case | How to Handle |
---|---|
Empty positive_feedback or negative_feedback array | Initialize the feedback words as empty sets to avoid errors when checking for inclusion. |
Empty report array | Return an empty list if no student reports are available. |
k is zero | Return an empty list if k is zero, as no students need to be rewarded. |
k is greater than the number of students | Return the sorted reward list of all students if k exceeds the total number of students. |
Reports contain empty strings | Handle empty strings in reports by skipping them or treating them as not containing feedback words to avoid errors. |
Large number of students or long reports causing memory issues | Consider using efficient data structures or algorithms (e.g., min-heap of fixed size k) to minimize memory usage. |
Tie scores for top K students. | Sort the scores based on student ID as a secondary key to ensure a deterministic result in the event of ties. |
Very long reports which may cause timeouts due to excessive processing. | Optimize the report processing by using efficient string search algorithms or limiting the number of words processed per report. |