Watch 9 video solutions for Design Exam Scores Tracker, a medium level problem involving Array, Binary Search, Design. This walkthrough by Abhinav Awasthi has 1,478 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Alice frequently takes exams and wants to track her scores and calculate the total scores over specific time periods.
Implement the ExamTracker class:
ExamTracker(): Initializes the ExamTracker object.void record(int time, int score): Alice takes a new exam at time time and achieves the score score.long long totalScore(int startTime, int endTime): Returns an integer that represents the total score of all exams taken by Alice between startTime and endTime (inclusive). If there are no recorded exams taken by Alice within the specified time interval, return 0.It is guaranteed that the function calls are made in chronological order. That is,
record() will be made with strictly increasing time.record() is called with time = t, then totalScore() will always be called with startTime <= endTime <= t.
Example 1:
Input:
["ExamTracker", "record", "totalScore", "record", "totalScore", "totalScore", "totalScore", "totalScore"]
[[], [1, 98], [1, 1], [5, 99], [1, 3], [1, 5], [3, 4], [2, 5]]
Output:
[null, null, 98, null, 98, 197, 0, 99]
Explanation
ExamTracker examTracker = new ExamTracker();98 + 99 = 197.
Constraints:
1 <= time <= 1091 <= score <= 1091 <= startTime <= endTime <= t, where t is the value of time from the most recent call of record().record() will be made with strictly increasing time.ExamTracker(), the first function call will always be record().105 calls will be made in total to record() and totalScore().Problem Overview: You need to design a system that tracks exam scores and efficiently answers queries about score ranges or aggregated statistics. The challenge is supporting repeated queries without scanning the entire dataset every time.
Approach 1: Brute Force Range Scan (Time: O(n) per query, Space: O(1))
The most direct approach stores all scores in an array. For every query, iterate through the entire array and compute the required statistic such as total scores, counts, or averages within a given range. This works because the array already contains all information needed to answer the query. However, each query requires scanning the full list, which becomes expensive when the number of scores or queries grows large. This approach is useful for understanding the problem but does not scale well.
Approach 2: Sorted Array + Prefix Sum (Time: O(n log n) preprocessing, O(log n + 1) query, Space: O(n))
Instead of repeatedly scanning the array, first sort the scores. Then build a prefix sum array where prefix[i] stores the cumulative total up to index i. Sorting allows efficient boundary discovery using binary search. For a query range, locate the left and right indices with binary search and subtract prefix values to compute the result instantly. This eliminates repeated linear scans and reduces query cost dramatically.
Approach 3: Prefix Sum + Binary Search (Time: O(log n) per query, Space: O(n))
The optimal design maintains scores in a sorted structure and precomputes prefix sums. When a query arrives, perform two binary searches to find the first index >= lower bound and the last index <= upper bound. With those indices, compute the aggregated score using a simple prefix subtraction. Binary search ensures logarithmic lookup time, while prefix sums provide constant-time range aggregation. This approach leverages properties of a sorted array and is the standard technique for repeated range queries.
Recommended for interviews: Start by explaining the brute force scan to demonstrate understanding of the requirement. Then move to the Prefix Sum + Binary Search approach. Interviewers expect this optimization because it reduces query cost from O(n) to O(log n) while keeping the implementation simple and predictable.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force Range Scan | O(n) per query | O(1) | Small datasets or when queries are rare |
| Sorted Array + Prefix Sum | O(n log n) preprocessing, O(log n) query | O(n) | When scores are static and many range queries are expected |
| Prefix Sum + Binary Search | O(log n) per query | O(n) | Best for frequent queries requiring fast range aggregation |