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).
💡 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).
💡 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.
The key insight is to use two heaps to maintain a dynamic query position efficiently. The two heaps approach maintains O(log n) complexity per operation by keeping better locations in a max-heap and current/worse locations in a min-heap. Best approach: Two Heaps. Time: O((n + q) log n), Space: O(n)
Common Approaches
✓
Brute Force with Sorting
⏱️ Time: O(q × n log n)
Space: O(n)
Keep all locations in a list and sort them each time get() is called. This ensures we can always find the ith best location but is inefficient for frequent queries.
Two Heaps Approach
⏱️ Time: O((n + q) log n)
Space: O(n)
Maintain two heaps: a max-heap for locations before current query position and a min-heap for locations at and after query position. This allows O(log n) operations while keeping track of the current query index.
Brute Force with Sorting — Algorithm Steps
Store all locations in a list
On add(): append new location
On get(): sort entire list and return element at query index
Visualization
Tap to expand
Step-by-Step Walkthrough
1
Add Locations
Store locations in unsorted list
2
Query
Sort entire list by score (desc) then name (asc)
3
Return
Return location at query index
Code -
solution.c — C
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
typedef struct {
char name[100];
int score;
} Location;
typedef struct {
Location* locations;
int count;
int capacity;
int queryCount;
} SORTracker;
SORTracker* createTracker() {
SORTracker* tracker = malloc(sizeof(SORTracker));
tracker->locations = malloc(1000 * sizeof(Location));
tracker->count = 0;
tracker->capacity = 1000;
tracker->queryCount = 0;
return tracker;
}
void add(SORTracker* tracker, char* name, int score) {
strcpy(tracker->locations[tracker->count].name, name);
tracker->locations[tracker->count].score = score;
tracker->count++;
}
int compare(const void* a, const void* b) {
Location* la = (Location*)a;
Location* lb = (Location*)b;
if (la->score != lb->score) {
return lb->score - la->score; /* higher score first */
}
return strcmp(la->name, lb->name); /* lexicographically smaller name first */
}
char* get(SORTracker* tracker) {
tracker->queryCount++;
qsort(tracker->locations, tracker->count, sizeof(Location), compare);
return tracker->locations[tracker->queryCount - 1].name;
}
/* ── JSON helpers ─────────────────────────────────────────────────────────── */
/* Skip whitespace */
static int skip_ws(const char* s, int i) {
while (s[i] == ' ' || s[i] == '\t' || s[i] == '\r' || s[i] == '\n') i++;
return i;
}
/*
* Read a quoted JSON string starting at s[i] (which must be '"').
* Writes result into `out` and returns index after the closing '"'.
*/
static int read_string(const char* s, int i, char* out) {
i++; /* skip opening '"' */
int j = 0;
while (s[i] != '"' && s[i] != '\0') {
if (s[i] == '\\') i++; /* skip escape char */
out[j++] = s[i++];
}
out[j] = '\0';
i++; /* skip closing '"' */
return i;
}
/*
* Read a JSON integer (possibly negative) starting at s[i].
* Writes value into *val and returns index after the number.
*/
static int read_int(const char* s, int i, int* val) {
int sign = 1;
if (s[i] == '-') { sign = -1; i++; }
int n = 0;
while (isdigit((unsigned char)s[i])) {
n = n * 10 + (s[i] - '0');
i++;
}
*val = sign * n;
return i;
}
/* ── Main ─────────────────────────────────────────────────────────────────── */
int main() {
static char input[1 << 20]; /* 1 MB buffer */
if (!fgets(input, sizeof(input), stdin)) return 1;
SORTracker* tracker = createTracker();
/* Output buffer */
static char output[1 << 20];
int outLen = 0;
output[outLen++] = '[';
int firstOp = 1;
int i = 0;
int len = (int)strlen(input);
/* Expect outer '[' */
i = skip_ws(input, i);
if (input[i] == '[') i++;
while (i < len) {
i = skip_ws(input, i);
/* End of outer array */
if (input[i] == ']') break;
/* Skip commas between operations */
if (input[i] == ',') { i++; continue; }
/* Each operation is an inner array: ["opName", arg1, arg2, ...] */
if (input[i] != '[') { i++; continue; }
i++; /* skip '[' */
i = skip_ws(input, i);
/* Read operation name */
char opName[64] = {0};
if (input[i] == '"') {
i = read_string(input, i, opName);
} else {
i++; continue;
}
/* Separator before next result */
if (!firstOp) {
output[outLen++] = ',';
}
firstOp = 0;
if (strcmp(opName, "SORTracker") == 0) {
/* Constructor — append null */
memcpy(output + outLen, "null", 4);
outLen += 4;
} else if (strcmp(opName, "add") == 0) {
/* ["add", "name", score] */
i = skip_ws(input, i);
if (input[i] == ',') i++;
i = skip_ws(input, i);
char locName[100] = {0};
i = read_string(input, i, locName);
i = skip_ws(input, i);
if (input[i] == ',') i++;
i = skip_ws(input, i);
int score = 0;
i = read_int(input, i, &score);
add(tracker, locName, score);
memcpy(output + outLen, "null", 4);
outLen += 4;
} else if (strcmp(opName, "get") == 0) {
/* ["get"] */
char* result = get(tracker);
output[outLen++] = '"';
int rlen = (int)strlen(result);
memcpy(output + outLen, result, rlen);
outLen += rlen;
output[outLen++] = '"';
}
/* Skip to end of inner array ']' */
while (i < len && input[i] != ']') i++;
if (input[i] == ']') i++;
}
output[outLen++] = ']';
output[outLen++] = '\0';
printf("%s\n", output);
free(tracker->locations);
free(tracker);
return 0;
}
Time & Space Complexity
Time Complexity
⏱️
O(q × n log n)
q queries, each requiring O(n log n) sorting
n
2n
⚡ Linearithmic
Space Complexity
O(n)
Store all n locations in list
n
2n
⚡ Linearithmic Space
28.4K Views
MediumFrequency
~35 minAvg. Time
892 Likes
Ln 1, Col 1
Smart Actions
💡Explanation
AI Ready
💡 SuggestionTabto acceptEscto dismiss
// Output will appear here after running code
Code Editor Closed
Click the red button to reopen
Algorithm Visualization
Pinch to zoom • Tap outside to close
Test Cases
0 passed
0 failed
3 pending
Select Compiler
Choose a programming language
Compiler list would appear here...
AI Editor Features
Header Buttons
💡
Explain
Get a detailed explanation of your code. Select specific code or analyze the entire file. Understand algorithms, logic flow, and complexity.
🔧
Fix
Automatically detect and fix issues in your code. Finds bugs, syntax errors, and common mistakes. Shows you what was fixed.
💡
Suggest
Get improvement suggestions for your code. Best practices, performance tips, and code quality recommendations.
💬
Ask AI
Open an AI chat assistant to ask any coding questions. Have a conversation about your code, get help with debugging, or learn new concepts.
Smart Actions (Slash Commands)
🔧
/fix Enter
Find and fix issues in your code. Detects common problems and applies automatic fixes.
💡
/explain Enter
Get a detailed explanation of what your code does, including time/space complexity analysis.
🧪
/tests Enter
Automatically generate unit tests for your code. Creates comprehensive test cases.
📝
/docs Enter
Generate documentation for your code. Creates docstrings, JSDoc comments, and type hints.
⚡
/optimize Enter
Get performance optimization suggestions. Improve speed and reduce memory usage.
AI Code Completion (Copilot-style)
👻
Ghost Text Suggestions
As you type, AI suggests code completions shown in gray text. Works with keywords like def, for, if, etc.
Tabto acceptEscto dismiss
💬
Comment-to-Code
Write a comment describing what you want, and AI generates the code. Try: # two sum, # binary search, # fibonacci
💡
Pro Tip: Select specific code before using Explain, Fix, or Smart Actions to analyze only that portion. Otherwise, the entire file will be analyzed.