Problem 506 Relative Ranks
Table of Contents
Problem Statement
Link - Problem 506
Question
You are given an integer array score of size n, where score[i] is the score of the ith athlete in a competition. All the scores are guaranteed to be unique.
The athletes are placed based on their scores, where the 1st place athlete has the highest score, the 2nd place athlete has the 2nd highest score, and so on. The placement of each athlete determines their rank:
- The
1stplace athlete’s rank is"Gold Medal". - The
2ndplace athlete’s rank is"Silver Medal". - The
3rdplace athlete’s rank is"Bronze Medal". - For the
4thplace to thenthplace athlete, their rank is their placement number (i.e., thexthplace athlete’s rank is"x").
Return an array answer of size n where answer[i] is the rank of the ith athlete.
Example 1
Input: score = [5,4,3,2,1]
Output: ["Gold Medal","Silver Medal","Bronze Medal","4","5"]
Explanation: The placements are [1st, 2nd, 3rd, 4th, 5th].
Example 2
Input: score = [10,3,8,9,4]
Output: ["Gold Medal","5","Bronze Medal","Silver Medal","4"]
Explanation: The placements are [1st, 5th, 3rd, 2nd, 4th].
Constraints
n == score.length1<= n <=10^40<= score[i] <=10^6- All the values in score are unique.
Solution
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
auto comparePair = [](const pair<int,int>& a,const pair<int,int>& b)
{
return a.first<b.first;
};
priority_queue<pair<int,int>, vector<pair<int,int>>, decltype(comparePair)> maxHeap;
for(int i = 0;i<score.size();i++)
maxHeap.push(make_pair(score[i],i));
vector<string>answer(score.size());
pair<int,int> holder;
int place = 0;
vector<string>places = {"Gold Medal","Silver Medal","Bronze Medal"};
while(!maxHeap.empty() && place <3)
{
holder = maxHeap.top();
maxHeap.pop();
answer[holder.second] = places[place];
place++;
}
while(!maxHeap.empty())
{
holder = maxHeap.top();
maxHeap.pop();
answer[holder.second] = to_string(++place);
}
return answer;
}
};
Complexity Analysis
Time: O(nlogn)Space: O(n)
Explanation
1. Intuition
- Since the scores need to be relatively ordered in decreasing order, along with the index which they occured.
- We can use a priority queue to store the scores and their index.
- We would need to have a custom comparator to compare the scores.
- This needs to be a max heap, so that we can get the highest score first.
2. Implementation
- We can use a priority queue to store the scores and their index.
- We can use a custom comparator to compare the scores.
- The custom comparator
comparePaircompares the pair<score,index_which_it_occured>. - The lambda function
comparePairdoesa.first<b.firstbecause internally the priority queue is a max heap, hence the highest score would be at the top. - The custom comparator ensures that the the pair with highest
scoreis at the top of the heap. - The keyword
decltypeis used to get the type of the lambda function. - Priority queue needs to have a callable object as a comparator, hence we pass the lambda function
comparePair. - We will first push the scores and their index into the priority queue.
- We will have a vector of strings
answerto store the ranks of the athletes. - We will have a variable
placeto keep track of the rank. - We will have a vector of strings
placesto store themedalsof the athletes. - We will iterate the priority queue until the
placeis less than3. - We will pop the top element from the priority queue.
- We will assign the rank to the athlete based on the
place. 1stplace athlete’s rank is"Gold Medal".2ndplace athlete’s rank is"Silver Medal".3rdplace athlete’s rank is"Bronze Medal".- We will increment the
placeafter assigning the rank each time. - Then check if there are any more athletes left.
- If there are any athletes left, assign the rank based on the
place. - The ranks is a string hence use the
to_stringfunction to convert the integer to string. - Return the
answervector.
Alternate Solution
- A solution with a map can be used to store the scores and their index.
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
map<int, int> mp1;
vector<string> result(n);
for (int i = 0; i < n; i++) {
mp1[score[i]] = i;
}
sort(score.begin(), score.end(), greater<int>());
for (int i = 0; i < n; i++) {
if (i == 0) {
result[mp1[score[i]]] = "Gold Medal";
} else if (i == 1) {
result[mp1[score[i]]] = "Silver Medal";
} else if (i == 2) {
result[mp1[score[i]]] = "Bronze Medal";
} else {
result[mp1[score[i]]] = to_string(i + 1);
}
}
return result;
}
};
Time Complexity: O(nlogn)
Space Complexity: O(n)
- A solution with built in comparator for priority queue can be used.
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
std::ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
priority_queue<pair<int,int>> maxHeap;
for(int i = 0;i<score.size();i++)
maxHeap.push(make_pair(score[i],i));
vector<string>answer(score.size());
pair<int,int> holder;
int place = 0;
vector<string>places = {"Gold Medal","Silver Medal","Bronze Medal"};
while(!maxHeap.empty() && place <3)
{
holder = maxHeap.top();
maxHeap.pop();
answer[holder.second] = places[place];
place++;
}
while(!maxHeap.empty())
{
holder = maxHeap.top();
maxHeap.pop();
answer[holder.second] = to_string(++place);
}
return answer;
}
};
This problem demonstrtaes the use of priority queue and custom comparators to solve the problem. The alternate solutions are also provided for the same problem.