↓快轉到主要內容
  1. LeetCode/

LeetCode 3709: Design Exam Scores Tracker

·1 分鐘· ·
LeetCode Medium Binary-Search Prefix-Sum Design
Wei Yi Chung
作者
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
目錄

基本資料
#

難易度: medium 第一次嘗試:2025-10-11

  • 提交紀錄:Wrong Answer → Runtime Error → Wrong Answer → Accepted

解題思路
#

record 的時間嚴格遞增,所以時間陣列本身就是排好序的,不需要額外排序。

  • times:所有紀錄的時間。
  • prefix:分數的前綴和,prefix[i] 是前 i 筆的總和,prefix[0] = 0。

查詢 [start, end] 時:

左邊界 = 第一個 time >= start 的位置 = bisect_left(times, start)
右邊界 = 第一個 time >  end   的位置 = bisect_right(times, end)
總分   = prefix[右邊界] - prefix[左邊界]

prefix 前面多放一個 0,就不用處理「左邊界是 0」的特殊情況。

我的嘗試
#

WA 和 RE:mid 少了括號
#

mid = left + right // 2       # 等於 left + (right // 2)

// 的優先順序比 + 高,所以 mid 會超過正確範圍,有時找錯位置(WA),有時直接越界(RE)。

WA:查詢區間沒有任何紀錄
#

修好 mid 之後,查詢的範圍裡如果沒有任何考試,算出來的左邊界會大於右邊界,結果變成負數或讀錯位置。最後加了一堆邊界判斷才 AC。

根本原因是前綴和沒有在最前面放 0,所以要一直特判「左邊界是不是 0」。改成 prefix[0] = 0 加上左閉右開的兩個邊界之後,這些特判都不需要了:沒有紀錄時兩個邊界相等,相減自然是 0。

正確解法
#

import bisect

class ExamTracker:

    def __init__(self):
        self.times = []
        self.prefix = [0]

    def record(self, time: int, score: int) -> None:
        self.times.append(time)
        self.prefix.append(self.prefix[-1] + score)

    def totalScore(self, startTime: int, endTime: int) -> int:
        lo = bisect.bisect_left(self.times, startTime)
        hi = bisect.bisect_right(self.times, endTime)
        return self.prefix[hi] - self.prefix[lo]

複雜度
#

record 是 O(1),totalScore 是 O(log n)。空間 O(n)。

要特別避免的錯誤
#

  • mid = left + right // 2:少了括號。
  • 前綴和沒有在最前面放 0,導致一堆特判。
  • 區間內沒有紀錄時沒有回傳 0。

面試口說整理
#

紀錄的時間嚴格遞增,所以我直接存時間陣列和分數的前綴和,前綴和前面多放一個 0。查詢時用 bisect_left 找第一個時間不小於起點的位置、bisect_right 找第一個時間大於終點的位置,前綴和相減就是總分;沒有紀錄時兩個位置相同,結果自然是 0。記錄 O(1),查詢 O(log n)。

相關文章

LeetCode 3508: Implement Router
·2 分鐘
LeetCode Medium Design Binary-Search Queue Hash-Map
LeetCode 3508 解題筆記:queue 管 FIFO、set 判重複、每個目的地一個遞增的時間陣列,查詢用 bisect
LeetCode 981: Time Based Key-Value Store
·2 分鐘
LeetCode Medium Hash-Table String Binary-Search Design
LeetCode 981 解題筆記:每個 key 存一個 (timestamp, value) 的 list,timestamp 是遞增的;get 時二分找最後一個 timestamp <= 查詢時間的
LeetCode 209: Minimum Size Subarray Sum
·1 分鐘
LeetCode Daily Medium Array Sliding-Window Two-Pointers Prefix-Sum Binary-Search
滑動視窗與雙指針,最小化子陣列長度(總和 ≥ target)。
LeetCode 2874: Maximum Value of an Ordered Triplet II
·1 分鐘
LeetCode Medium Prefix-Sum Array
LeetCode 2874 解題筆記:枚舉中間的 j,左邊取前綴最大、右邊取後綴最大;也可以一次掃描維護最大值和最大差
LeetCode 1248: Count Number of Nice Subarrays
·2 分鐘
LeetCode Medium Sliding-Window Prefix-Sum Hash-Table Array
LeetCode 1248 解題筆記:「剛好 k 個奇數」不單調,改成「最多 k 個」減「最多 k - 1 個」;或用前綴和 + 雜湊表
LeetCode 3613: Minimize Maximum Component Cost
·1 分鐘
LeetCode Medium Union-Find Graph Sorting Binary-Search
LeetCode 3613 解題筆記:邊由小到大加進 Union-Find,剛好剩 k 塊時那條邊的權重就是答案;n <= k 時回傳 0