|
| 1 | +# 2102. Sequentially Ordinal Rank Tracker |
| 2 | +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. |
| 3 | + |
| 4 | +You are building a system that tracks the ranking of locations with the system initially starting with no locations. It supports: |
| 5 | + |
| 6 | +* **Adding** scenic locations, **one at a time**. |
| 7 | +* **Querying** the <code>i<sup>th</sup></code> **best** location of **all locations already added**, where `i` is the number of times the system has been queried (including the current query). |
| 8 | + * For example, when the system is queried for the <code>4<sup>th</sup></code> time, it returns the <code>4<sup>th</sup></code> best location of all locations already added. |
| 9 | + |
| 10 | +Note that 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. |
| 11 | + |
| 12 | +Implement the `SORTracker` class: |
| 13 | + |
| 14 | +* `SORTracker()` Initializes the tracker system. |
| 15 | +* `void add(string name, int score)` Adds a scenic location with `name` and `score` to the system. |
| 16 | +* `string get()` Queries and returns the <code>i<sup>th</sup></code> best location, where `i` is the number of times this method has been invoked (including this invocation). |
| 17 | + |
| 18 | +#### Example 1: |
| 19 | +<pre> |
| 20 | +<strong>Input:</strong> |
| 21 | +["SORTracker", "add", "add", "get", "add", "get", "add", "get", "add", "get", "add", "get", "get"] |
| 22 | +[[], ["bradford", 2], ["branford", 3], [], ["alps", 2], [], ["orland", 2], [], ["orlando", 3], [], ["alpine", 2], [], []] |
| 23 | +<strong>Output:</strong> |
| 24 | +[null, null, null, "branford", null, "alps", null, "bradford", null, "bradford", null, "bradford", "orland"] |
| 25 | +<strong>Explanation:</strong> |
| 26 | +SORTracker tracker = new SORTracker(); // Initialize the tracker system. |
| 27 | +tracker.add("bradford", 2); // Add location with name="bradford" and score=2 to the system. |
| 28 | +tracker.add("branford", 3); // Add location with name="branford" and score=3 to the system. |
| 29 | +tracker.get(); // The sorted locations, from best to worst, are: branford, bradford. |
| 30 | + // Note that branford precedes bradford due to its higher score (3 > 2). |
| 31 | + // This is the 1st time get() is called, so return the best location: "branford". |
| 32 | +tracker.add("alps", 2); // Add location with name="alps" and score=2 to the system. |
| 33 | +tracker.get(); // Sorted locations: branford, alps, bradford. |
| 34 | + // Note that alps precedes bradford even though they have the same score (2). |
| 35 | + // This is because "alps" is lexicographically smaller than "bradford". |
| 36 | + // Return the 2nd best location "alps", as it is the 2nd time get() is called. |
| 37 | +tracker.add("orland", 2); // Add location with name="orland" and score=2 to the system. |
| 38 | +tracker.get(); // Sorted locations: branford, alps, bradford, orland. |
| 39 | + // Return "bradford", as it is the 3rd time get() is called. |
| 40 | +tracker.add("orlando", 3); // Add location with name="orlando" and score=3 to the system. |
| 41 | +tracker.get(); // Sorted locations: branford, orlando, alps, bradford, orland. |
| 42 | + // Return "bradford". |
| 43 | +tracker.add("alpine", 2); // Add location with name="alpine" and score=2 to the system. |
| 44 | +tracker.get(); // Sorted locations: branford, orlando, alpine, alps, bradford, orland. |
| 45 | + // Return "bradford". |
| 46 | +tracker.get(); // Sorted locations: branford, orlando, alpine, alps, bradford, orland. |
| 47 | + // Return "orland". |
| 48 | +</pre> |
| 49 | + |
| 50 | +#### Constraints: |
| 51 | +* `name` consists of lowercase English letters, and is unique among all locations. |
| 52 | +* `1 <= name.length <= 10` |
| 53 | +* <code>1 <= score <= 10<sup>5</sup></code> |
| 54 | +* At any time, the number of calls to `get` does not exceed the number of calls to `add`. |
| 55 | +* At most <code>4 * 10<sup>4</sup></code> calls **in total** will be made to `add` and `get`. |
| 56 | + |
| 57 | +## Solutions (Python) |
| 58 | + |
| 59 | +### 1. Solution |
| 60 | +```Python |
| 61 | +from sortedcontainers import SortedList |
| 62 | + |
| 63 | + |
| 64 | +class SORTracker: |
| 65 | + |
| 66 | + def __init__(self): |
| 67 | + self.locations = SortedList() |
| 68 | + self.i = 0 |
| 69 | + |
| 70 | + def add(self, name: str, score: int) -> None: |
| 71 | + self.locations.add((-score, name)) |
| 72 | + |
| 73 | + def get(self) -> str: |
| 74 | + self.i += 1 |
| 75 | + |
| 76 | + return self.locations[self.i - 1][1] |
| 77 | + |
| 78 | +# Your SORTracker object will be instantiated and called as such: |
| 79 | +# obj = SORTracker() |
| 80 | +# obj.add(name,score) |
| 81 | +# param_2 = obj.get() |
| 82 | +``` |
0 commit comments