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.
Input & Output
Example 1 — Basic Case
$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]
💡 Note:Student 1: 'studious' (+3) = 3 points. Student 2: 'smart' (+3) = 3 points. Both have same score, so lower ID (1) ranks higher.
Example 2 — With Negative Feedback
$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
The key insight is to use hash sets for O(1) word lookup when calculating student scores, then sort by score (descending) and ID (ascending) for tie-breaking. Best approach uses hash map optimization with Time: O(n×m + s log s), Space: O(p + s).
Common Approaches
✓
Brute Force with Linear Search
⏱️ Time: O(n × m × p + s log s)
Space: O(s)
For each report, scan through all positive and negative feedback arrays to count matches. Then sort all students by score and ID, returning top k.
Hash Set Optimization
⏱️ Time: O(p + n × m + s log s)
Space: O(p + s)
Convert positive and negative feedback arrays to hash sets for constant-time word lookup. Calculate each student's score and sort by score then ID.
Priority Queue for Top-K
⏱️ Time: O(p + n × m + s log k)
Space: O(p + k)
Use hash sets for word lookup, then maintain a min-heap of size k to track top students. This avoids sorting all students when k is much smaller than total students.
Brute Force with Linear Search — Algorithm Steps
Step 1: For each report, count positive/negative words by linear search
Step 2: Calculate total score for each student
Step 3: Sort all students and return top k
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Process Report
Split report into words
2
Search Words
Linear search each word in feedback arrays
3
Calculate Score
Sum up points for each student
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORDS 1000
#define MAX_STUDENTS 1000
#define MAX_LINE_LEN 10000
#define MAX_WORD_LEN 100
static char positive_words[MAX_WORDS][MAX_WORD_LEN];
static char negative_words[MAX_WORDS][MAX_WORD_LEN];
static char reports[MAX_WORDS][MAX_LINE_LEN];
static int student_ids[MAX_WORDS];
static int student_scores[MAX_STUDENTS];
static int unique_students[MAX_STUDENTS];
int parseStringArray(char* line, char words[][MAX_WORD_LEN]) {
int count = 0;
char* start = strchr(line, '[');
char* end = strrchr(line, ']');
if (!start || !end) return 0;
char* pos = start + 1;
while (pos < end && count < MAX_WORDS) {
// Find opening quote
char* quote1 = strchr(pos, '"');
if (!quote1 || quote1 >= end) break;
// Find closing quote
char* quote2 = strchr(quote1 + 1, '"');
if (!quote2 || quote2 >= end) break;
// Copy word
int len = quote2 - quote1 - 1;
if (len < MAX_WORD_LEN) {
strncpy(words[count], quote1 + 1, len);
words[count][len] = '\0';
count++;
}
pos = quote2 + 1;
}
return count;
}
int parseReports(char* line, char reports[][MAX_LINE_LEN]) {
int count = 0;
char* start = strchr(line, '[');
char* end = strrchr(line, ']');
if (!start || !end) return 0;
char* pos = start + 1;
while (pos < end && count < MAX_WORDS) {
// Find opening quote
char* quote1 = strchr(pos, '"');
if (!quote1 || quote1 >= end) break;
// Find closing quote
char* quote2 = strchr(quote1 + 1, '"');
if (!quote2 || quote2 >= end) break;
// Copy entire report
int len = quote2 - quote1 - 1;
if (len < MAX_LINE_LEN) {
strncpy(reports[count], quote1 + 1, len);
reports[count][len] = '\0';
count++;
}
pos = quote2 + 1;
}
return count;
}
int parseIntArray(char* line, int* arr) {
int count = 0;
char* start = strchr(line, '[');
char* end = strrchr(line, ']');
if (!start || !end) return 0;
char* pos = start + 1;
while (pos < end && count < MAX_WORDS) {
char* next;
int val = strtol(pos, &next, 10);
if (next == pos) break;
arr[count++] = val;
pos = next;
while (pos < end && (*pos == ',' || *pos == ' ')) pos++;
}
return count;
}
int* solution(int pos_count, int neg_count, int report_count, int k, int* returnSize) {
// Initialize scores
for (int i = 0; i < MAX_STUDENTS; i++) {
student_scores[i] = 0;
}
for (int i = 0; i < report_count; i++) {
int student = student_ids[i];
int score = 0;
// Make a copy of the report for strtok
char report_copy[MAX_LINE_LEN];
strcpy(report_copy, reports[i]);
// Parse words from report
char* word = strtok(report_copy, " ");
while (word != NULL) {
// Linear search in positive feedback
int found = 0;
for (int j = 0; j < pos_count; j++) {
if (strcmp(word, positive_words[j]) == 0) {
score += 3;
found = 1;
break;
}
}
// Linear search in negative feedback
if (!found) {
for (int j = 0; j < neg_count; j++) {
if (strcmp(word, negative_words[j]) == 0) {
score -= 1;
break;
}
}
}
word = strtok(NULL, " ");
}
student_scores[student] += score;
}
// Get unique students
int student_count = 0;
for (int i = 0; i < report_count; i++) {
int student = student_ids[i];
int exists = 0;
for (int j = 0; j < student_count; j++) {
if (unique_students[j] == student) {
exists = 1;
break;
}
}
if (!exists) {
unique_students[student_count++] = student;
}
}
// Sort students by score (desc) then by ID (asc)
for (int i = 0; i < student_count - 1; i++) {
for (int j = 0; j < student_count - 1 - i; j++) {
int a = unique_students[j];
int b = unique_students[j + 1];
if (student_scores[a] < student_scores[b] ||
(student_scores[a] == student_scores[b] && a > b)) {
unique_students[j] = b;
unique_students[j + 1] = a;
}
}
}
int* result = (int*)malloc(k * sizeof(int));
for (int i = 0; i < k; i++) {
result[i] = unique_students[i];
}
*returnSize = k;
return result;
}
void parseArray(const char* str, int* arr, int* size) {
*size = 0;
const char* p = str;
while (*p && *p != '[') p++;
if (*p == '[') p++;
while (*p && *p != ']') {
while (*p == ' ' || *p == ',') p++;
if (*p == ']' || *p == '\0') break;
arr[(*size)++] = (int)strtol(p, (char**)&p, 10);
}
}
int main() {
char line[MAX_LINE_LEN];
fgets(line, sizeof(line), stdin);
int pos_count = parseStringArray(line, positive_words);
fgets(line, sizeof(line), stdin);
int neg_count = parseStringArray(line, negative_words);
fgets(line, sizeof(line), stdin);
int report_count = parseReports(line, reports);
fgets(line, sizeof(line), stdin);
parseIntArray(line, student_ids);
fgets(line, sizeof(line), stdin);
int k = atoi(line);
int returnSize;
int* result = solution(pos_count, neg_count, report_count, k, &returnSize);
printf("[");
for (int i = 0; i < returnSize; i++) {
if (i > 0) printf(",");
printf("%d", result[i]);
}
printf("]\n");
free(result);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(n × m × p + s log s)
n reports × m words per report × p feedback words + s students sorted
n
2n
⚡ Linearithmic
Space Complexity
O(s)
HashMap to store scores for s unique students
n
2n
✓ Linear Space
12.4K Views
MediumFrequency
~25 minAvg. Time
350 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.