Sequentially Ordinal Rank Tracker - Problem

A scenic location is represented by its name and attractiveness score, where name is a unique string among all locations and score is an integer. Locations can be ranked from the best to the worst. The higher the score, the better the location. If the scores of two locations are equal, then the location with the lexicographically smaller name is better.

You are building a system that tracks the ranking of locations with the system initially starting with no locations. It supports:

  • Adding scenic locations, one at a time.
  • Querying the ith best location of all locations already added, where i is the number of times the system has been queried (including the current query).

For example, when the system is queried for the 4th time, it returns the 4th best location of all locations already added.

Note: The test data are generated so that at any time, the number of queries does not exceed the number of locations added to the system.

Implement the SORTracker class:

  • SORTracker() Initializes the tracker system.
  • void add(string name, int score) Adds a scenic location with name and score to the system.
  • string get() Queries and returns the ith best location, where i is the number of times this method has been invoked (including this invocation).

Input & Output

Example 1 — Basic Operations
$ Input: [["SORTracker"],["add","bradford",2],["add","branford",3],["get"],["add","alps",2],["get"],["add","orland",2],["get"],["add","orlando",3],["get"],["add","alpine",2],["get"]]
Output: [null,null,null,"branford",null,"alps",null,"bradford",null,"bradford",null,"bradford"]
💡 Note: Step by step: 1st get() returns best location (branford,3). 2nd get() returns 2nd best (alps,2 - lexicographically smaller than bradford,2). 3rd get() returns 3rd best (bradford,2). Subsequent queries continue from 3rd position.
Example 2 — Score Ties
$ Input: [["SORTracker"],["add","beach",5],["add","lake",5],["get"],["add","forest",3],["get"]]
Output: [null,null,null,"beach",null,"beach"]
💡 Note: When scores are equal (beach,5 and lake,5), lexicographically smaller name wins. 1st get() returns "beach", 2nd get() returns "beach" again (still 2nd best overall).
Example 3 — Progressive Ranking
$ Input: [["SORTracker"],["add","mountain",10],["get"],["add","valley",8],["get"],["add","river",12],["get"]]
Output: [null,null,"mountain",null,"mountain",null,"river"]
💡 Note: 1st get() returns only location (mountain,10). 2nd get() returns 2nd best (mountain,10). When river,12 is added, it becomes best, so 3rd get() returns river,12.

Constraints

  • 1 ≤ name.length ≤ 10
  • -105 ≤ score ≤ 105
  • At most 4 × 104 calls total to add and get

Visualization

Tap to expand
Sequentially Ordinal Rank Tracker: Dynamic Location RankingOperations:add("mountain", 10)add("beach", 8)get() → 1st queryadd("lake", 6)get() → 2nd queryRanking (Score ↓, Name ↑):mountain, 10beach, 8lake, 6← 1st best← 2nd best← 3rd bestQuery Results:1st get() = "mountain"(1st best location)2nd get() = "beach"(2nd best location)Challenge: Efficiently maintain ranking as locations are addedSolution: Use two heaps to track query position dynamicallyKey: Query position advances with each get() call
Understanding the Visualization
1
Input
Stream of add(name, score) and get() operations
2
Ranking
Locations ranked by score (desc), then name (asc)
3
Query
Return ith best location where i = query number
Key Takeaway
🎯 Key Insight: Use two heaps to efficiently maintain the current query position without sorting all locations repeatedly
Asked in
Google 23 Amazon 18 Microsoft 15 Apple 12
28.4K Views
Medium Frequency
~35 min Avg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡 Explanation
AI Ready
💡 Suggestion Tab to accept Esc to dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen