↓Skip to main content
  1. LeetCode/

LeetCode 2102: Sequentially Ordinal Rank Tracker

·3 mins· ·
LeetCode Hard Heap Design Two-Heaps
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: hard First Attempt: 2026-08-01

  • Submissions: Accepted (first try)

Approach
#

The i-th query returns the i-th best location, and i only grows by 1 per query.

Split all locations between two heaps:

  • top: the best k locations, where k is the number of queries so far. Its top is the worst of those k, i.e. rank k.
  • rest: everything else. Its top is the best of them, i.e. rank k + 1.

Operations:

  • add: put the new location into top, then move the worst of top into rest. top keeps its size, and everything in top stays better than everything in rest.
  • get: k grows by 1, so move the best of rest into top; the top of top is now rank k.

The ordering wrinkle
#

“Higher score is better; on ties, the lexicographically smaller name is better.” For rest, taking the best is easy with (-score, name). But top needs the worst: lower score is worse, and on ties the larger name is worse. Strings cannot be negated, so define a class with __lt__.

My Solution
#

import heapq

class WorstFirst:
    """The heap top is the worst: lower score, or larger name on equal scores."""
    def __init__(self, score: int, name: str):
        self.score = score
        self.name = name

    def __lt__(self, other: "WorstFirst") -> bool:
        if self.score != other.score:
            return self.score < other.score
        return self.name > other.name

class SORTracker:

    def __init__(self):
        self.top = []        # the best k; top is rank k
        self.rest = []       # everything else as (-score, name); top is rank k+1

    def add(self, name: str, score: int) -> None:
        heapq.heappush(self.top, WorstFirst(score, name))
        worst = heapq.heappop(self.top)
        heapq.heappush(self.rest, (-worst.score, worst.name))

    def get(self) -> str:
        neg_score, name = heapq.heappop(self.rest)
        heapq.heappush(self.top, WorstFirst(-neg_score, name))
        return self.top[0].name

Complexity
#

add and get are both O(log n); space O(n).

Mistakes to Avoid
#

  • Putting new locations straight into rest: if one beats the worst of top, top stops being the real top k.
  • Faking reversed string order with tricks such as (score, reversed string); it is error-prone. A custom __lt__ is clearer.

Interview Explanation
#

The queried rank grows by one each time, so I keep two heaps: one for the top k, whose top is rank k, and one for the rest, whose top is rank k + 1. On add, the new location goes into the top-k heap and its worst element moves to the other heap; on get, the best of the other heap moves over and the top-k heap’s top is the answer. Since “larger name is worse” cannot be expressed with negation, I define __lt__. Both operations are O(log n).

Related

LeetCode 759: Employee Free Time
·2 mins
LeetCode Hard Heap K-Way-Merge Intervals Sweep-Line
LeetCode 759 note: k-way merge all work intervals by start; any gap after the latest end so far is common free time
LeetCode 3885: Design Event Manager
·2 mins
LeetCode Medium Heap Design Hash-Map Lazy-Deletion
LeetCode 3885 note: a dict of current priorities plus a max-heap with lazy deletion, validated on pop
LeetCode 3815: Design Auction System
·3 mins
LeetCode Medium Heap Design Hash-Map Lazy-Deletion
LeetCode 3815 note: one max-heap per item, push a new entry on every bid change, and drop stale entries on query
LeetCode 632: Smallest Range Covering Elements from K Lists
·3 mins
LeetCode Hard Heap K-Way-Merge Sliding-Window
LeetCode 632 note: a heap of each list’s current element plus the running maximum; always advance the smallest
LeetCode 2402: Meeting Rooms III
·3 mins
LeetCode Hard Heap Sorting Simulation Intervals
LeetCode 2402 note: one heap for free rooms and one for busy rooms; a delayed meeting keeps its original length
LeetCode 2392: Build a Matrix With Conditions
·2 mins
LeetCode Hard Graph Topological-Sort Matrix
LeetCode 2392 note: row and column conditions are independent, so run one topological sort for each; put x at its row and column positions, and return an empty matrix if either has a cycle