Off-by-one on range boundaries
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.
Move from brute-force thinking to an efficient approach using core interview patterns strategy.
Table: Scores
+-------------+---------+ | Column Name | Type | +-------------+---------+ | student_id | int | | subject | varchar | | score | int | | exam_date | varchar | +-------------+---------+ (student_id, subject, exam_date) is the primary key for this table. Each row contains information about a student's score in a specific subject on a particular exam date. score is between 0 and 100 (inclusive).
Write a solution to find the students who have shown improvement. A student is considered to have shown improvement if they meet both of these conditions:
Return the result table ordered by student_id, subject in ascending order.
The result format is in the following example.
Example:
Input:
Scores table:
+------------+----------+-------+------------+ | student_id | subject | score | exam_date | +------------+----------+-------+------------+ | 101 | Math | 70 | 2023-01-15 | | 101 | Math | 85 | 2023-02-15 | | 101 | Physics | 65 | 2023-01-15 | | 101 | Physics | 60 | 2023-02-15 | | 102 | Math | 80 | 2023-01-15 | | 102 | Math | 85 | 2023-02-15 | | 103 | Math | 90 | 2023-01-15 | | 104 | Physics | 75 | 2023-01-15 | | 104 | Physics | 85 | 2023-02-15 | +------------+----------+-------+------------+
Output:
+------------+----------+-------------+--------------+ | student_id | subject | first_score | latest_score | +------------+----------+-------------+--------------+ | 101 | Math | 70 | 85 | | 102 | Math | 80 | 85 | | 104 | Physics | 75 | 85 | +------------+----------+-------------+--------------+
Explanation:
Result table is ordered by student_id, subject.
Problem summary: Table: Scores +-------------+---------+ | Column Name | Type | +-------------+---------+ | student_id | int | | subject | varchar | | score | int | | exam_date | varchar | +-------------+---------+ (student_id, subject, exam_date) is the primary key for this table. Each row contains information about a student's score in a specific subject on a particular exam date. score is between 0 and 100 (inclusive). Write a solution to find the students who have shown improvement. A student is considered to have shown improvement if they meet both of these conditions: Have taken exams in the same subject on at least two different dates Their latest score in that subject is higher than their first score Return the result table ordered by student_id, subject in ascending order. The result format is in the following example.
Start with the most direct exhaustive search. That gives a correctness anchor before optimizing.
Pattern signal: General problem-solving
{"headers":{"Scores":["student_id","subject","score","exam_date"]},"rows":{"Scores":[[101,"Math",70,"2023-01-15"],[101,"Math",85,"2023-02-15"],[101,"Physics",65,"2023-01-15"],[101,"Physics",60,"2023-02-15"],[102,"Math",80,"2023-01-15"],[102,"Math",85,"2023-02-15"],[103,"Math",90,"2023-01-15"],[104,"Physics",75,"2023-01-15"],[104,"Physics",85,"2023-02-15"]]}}Source-backed implementations are provided below for direct study and interview prep.
// Accepted solution for LeetCode #3421: Find Students Who Improved
// Auto-generated Java example from rust.
class Solution {
public void exampleSolution() {
}
}
// Reference (rust):
// // Accepted solution for LeetCode #3421: Find Students Who Improved
// pub fn sql_example() -> &'static str {
// r#"
// -- Accepted solution for LeetCode #3421: Find Students Who Improved
// WITH
// RankedScores AS (
// SELECT
// student_id,
// subject,
// score,
// exam_date,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date ASC
// ) AS rn_first,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date DESC
// ) AS rn_latest
// FROM Scores
// ),
// FirstAndLatestScores AS (
// SELECT
// f.student_id,
// f.subject,
// f.score AS first_score,
// l.score AS latest_score
// FROM
// RankedScores f
// JOIN RankedScores l ON f.student_id = l.student_id AND f.subject = l.subject
// WHERE f.rn_first = 1 AND l.rn_latest = 1
// )
// SELECT
// *
// FROM FirstAndLatestScores
// WHERE latest_score > first_score
// ORDER BY 1, 2;
// "#
// }
// Accepted solution for LeetCode #3421: Find Students Who Improved
// Auto-generated Go example from rust.
func exampleSolution() {
}
// Reference (rust):
// // Accepted solution for LeetCode #3421: Find Students Who Improved
// pub fn sql_example() -> &'static str {
// r#"
// -- Accepted solution for LeetCode #3421: Find Students Who Improved
// WITH
// RankedScores AS (
// SELECT
// student_id,
// subject,
// score,
// exam_date,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date ASC
// ) AS rn_first,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date DESC
// ) AS rn_latest
// FROM Scores
// ),
// FirstAndLatestScores AS (
// SELECT
// f.student_id,
// f.subject,
// f.score AS first_score,
// l.score AS latest_score
// FROM
// RankedScores f
// JOIN RankedScores l ON f.student_id = l.student_id AND f.subject = l.subject
// WHERE f.rn_first = 1 AND l.rn_latest = 1
// )
// SELECT
// *
// FROM FirstAndLatestScores
// WHERE latest_score > first_score
// ORDER BY 1, 2;
// "#
// }
# Accepted solution for LeetCode #3421: Find Students Who Improved
# Auto-generated Python example from rust.
def example_solution() -> None:
return
# Reference (rust):
# // Accepted solution for LeetCode #3421: Find Students Who Improved
# pub fn sql_example() -> &'static str {
# r#"
# -- Accepted solution for LeetCode #3421: Find Students Who Improved
# WITH
# RankedScores AS (
# SELECT
# student_id,
# subject,
# score,
# exam_date,
# ROW_NUMBER() OVER (
# PARTITION BY student_id, subject
# ORDER BY exam_date ASC
# ) AS rn_first,
# ROW_NUMBER() OVER (
# PARTITION BY student_id, subject
# ORDER BY exam_date DESC
# ) AS rn_latest
# FROM Scores
# ),
# FirstAndLatestScores AS (
# SELECT
# f.student_id,
# f.subject,
# f.score AS first_score,
# l.score AS latest_score
# FROM
# RankedScores f
# JOIN RankedScores l ON f.student_id = l.student_id AND f.subject = l.subject
# WHERE f.rn_first = 1 AND l.rn_latest = 1
# )
# SELECT
# *
# FROM FirstAndLatestScores
# WHERE latest_score > first_score
# ORDER BY 1, 2;
# "#
# }
// Accepted solution for LeetCode #3421: Find Students Who Improved
pub fn sql_example() -> &'static str {
r#"
-- Accepted solution for LeetCode #3421: Find Students Who Improved
WITH
RankedScores AS (
SELECT
student_id,
subject,
score,
exam_date,
ROW_NUMBER() OVER (
PARTITION BY student_id, subject
ORDER BY exam_date ASC
) AS rn_first,
ROW_NUMBER() OVER (
PARTITION BY student_id, subject
ORDER BY exam_date DESC
) AS rn_latest
FROM Scores
),
FirstAndLatestScores AS (
SELECT
f.student_id,
f.subject,
f.score AS first_score,
l.score AS latest_score
FROM
RankedScores f
JOIN RankedScores l ON f.student_id = l.student_id AND f.subject = l.subject
WHERE f.rn_first = 1 AND l.rn_latest = 1
)
SELECT
*
FROM FirstAndLatestScores
WHERE latest_score > first_score
ORDER BY 1, 2;
"#
}
// Accepted solution for LeetCode #3421: Find Students Who Improved
// Auto-generated TypeScript example from rust.
function exampleSolution(): void {
}
// Reference (rust):
// // Accepted solution for LeetCode #3421: Find Students Who Improved
// pub fn sql_example() -> &'static str {
// r#"
// -- Accepted solution for LeetCode #3421: Find Students Who Improved
// WITH
// RankedScores AS (
// SELECT
// student_id,
// subject,
// score,
// exam_date,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date ASC
// ) AS rn_first,
// ROW_NUMBER() OVER (
// PARTITION BY student_id, subject
// ORDER BY exam_date DESC
// ) AS rn_latest
// FROM Scores
// ),
// FirstAndLatestScores AS (
// SELECT
// f.student_id,
// f.subject,
// f.score AS first_score,
// l.score AS latest_score
// FROM
// RankedScores f
// JOIN RankedScores l ON f.student_id = l.student_id AND f.subject = l.subject
// WHERE f.rn_first = 1 AND l.rn_latest = 1
// )
// SELECT
// *
// FROM FirstAndLatestScores
// WHERE latest_score > first_score
// ORDER BY 1, 2;
// "#
// }
Use this to step through a reusable interview workflow for this problem.
Two nested loops check every pair or subarray. The outer loop fixes a starting point, the inner loop extends or searches. For n elements this gives up to n²/2 operations. No extra space, but the quadratic time is prohibitive for large inputs.
Most array problems have an O(n²) brute force (nested loops) and an O(n) optimal (single pass with clever state tracking). The key is identifying what information to maintain as you scan: a running max, a prefix sum, a hash map of seen values, or two pointers.
Review these before coding to avoid predictable interview regressions.
Wrong move: Loop endpoints miss first/last candidate.
Usually fails on: Fails on minimal arrays and exact-boundary answers.
Fix: Re-derive loops from inclusive/exclusive ranges before coding.