目录
题目
给你一个长度为 n 的整数数组 score ,其中 score[i] 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。
运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:
名次第 1 的运动员获金牌 "Gold Medal" 。
名次第 2 的运动员获银牌 "Silver Medal" 。
名次第 3 的运动员获铜牌 "Bronze Medal" 。
从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。
使用长度为 n 的数组 answer 返回获奖,其中 answer[i] 是第 i 位运动员的获奖情况。
解法
cpp
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
string desc[3] = {"Gold Medal", "Silver Medal", "Bronze Medal"};
vector<pair<int, int>> arr;
for (int i = 0; i < n; ++i) {
arr.emplace_back(make_pair(-score[i], i));
}
sort(arr.begin(), arr.end());
vector<string> ans(n);
for (int i = 0; i < n; ++i) {
if (i >= 3) {
ans[arr[i].second] = to_string(i + 1);
} else {
ans[arr[i].second] = desc[i];
}
}
return ans;
}
};
vector<pair<int, int>> arr;pair是什么类型
vector<pair<int, int>> arr; 是一个使用 C++ 标准库的 STL 容器 vector,其元素是 pair<int, int> 类型。换句话说,这是一个存储整数对的动态数组,每个元素都是一个由两个整数组成的 pair。
详细说明
vector 是一个动态数组,可以根据需要自动调整大小。
pair<int, int> 是一个包含两个整数(int 类型)的配对结构,first 和 second 分别代表这两个整数。
cpp
arr[i].second
用这个.second/.first来调用
这段代码的作用是解决一个排名问题:给定一个运动员的得分数组 score
,程序需要根据每位运动员的得分从高到低决定他们的排名。前 3 名的运动员分别获得 "Gold Medal"、"Silver Medal" 和 "Bronze Medal",其余的运动员获得他们的名次编号。
代码结构:
cpp
class Solution {
public:
vector<string> findRelativeRanks(vector<int>& score) {
int n = score.size();
string desc[3] = {"Gold Medal", "Silver Medal", "Bronze Medal"};
vector<pair<int, int>> arr;
for (int i = 0; i < n; ++i) {
arr.emplace_back(make_pair(-score[i], i)); // 1. 将每个分数和对应的索引作为 pair 存储
}
sort(arr.begin(), arr.end()); // 2. 对 arr 按照分数(负值)从小到大排序(即从大到小排序)
vector<string> ans(n); // 3. 创建存储结果的字符串向量
for (int i = 0; i < n; ++i) {
if (i >= 3) { // 4. 处理第 4 名及以后的情况,直接赋予名次
ans[arr[i].second] = to_string(i + 1);
} else { // 5. 前三名获得奖牌
ans[arr[i].second] = desc[i];
}
}
return ans; // 6. 返回结果
}
};
详细过程解析:
1. 输入:
给定一个整数数组 score
,表示各个运动员的得分,例如:
cpp
vector<int> score = {10, 3, 8, 9, 4};
2. 初始化变量:
cpp
int n = score.size();
string desc[3] = {"Gold Medal", "Silver Medal", "Bronze Medal"};
vector<pair<int, int>> arr;
n
是运动员的总数,n = 5
。desc[3]
是奖牌描述字符串数组,用于保存前 3 名的奖牌名称。arr
是一个pair
的动态数组,用来保存每个运动员的分数及其对应的索引。
3. 将分数和索引打包为 pair
:
cpp
for (int i = 0; i < n; ++i) {
arr.emplace_back(make_pair(-score[i], i));
}
- 这个循环将每个运动员的分数取负,并将其与运动员的索引
i
配对存入arr
中。取负的目的是为了让排序结果按分数从高到低排序,因为sort
默认是升序排序。
对于输入 score = {10, 3, 8, 9, 4}
,arr
的状态是:
arr = {(-10, 0), (-3, 1), (-8, 2), (-9, 3), (-4, 4)}
4. 排序 arr
:
cpp
sort(arr.begin(), arr.end());
- 经过排序后,
arr
会根据score[i]
的负值从小到大排列,即按原始得分从大到小排列。
排序后的 arr
:
arr = {(-10, 0), (-9, 3), (-8, 2), (-4, 4), (-3, 1)}
这个数组的含义是:分数最高的是 arr[0]
对应的索引 0 号运动员,第二高的是 arr[1]
对应的 3 号运动员,依此类推。
5. 生成名次:
cpp
vector<string> ans(n);
for (int i = 0; i < n; ++i) {
if (i >= 3) {
ans[arr[i].second] = to_string(i + 1);
} else {
ans[arr[i].second] = desc[i];
}
}
ans
是最终存储结果的数组,长度为n
。- 对于前 3 名运动员,分配奖牌名称。对于第 4 名及以后的运动员,分配具体名次编号。
逐步分配:
i = 0
:arr[0].second == 0
,即第 0 号运动员得分最高,获金牌"Gold Medal"
。i = 1
:arr[1].second == 3
,即第 3 号运动员得分第二,获银牌"Silver Medal"
。i = 2
:arr[2].second == 2
,即第 2 号运动员得分第三,获铜牌"Bronze Medal"
。i = 3
:arr[3].second == 4
,即第 4 号运动员得分第四,获得名次编号"4"
。i = 4
:arr[4].second == 1
,即第 1 号运动员得分第五,获得名次编号"5"
。
最终,ans
结果为:
ans = {"Gold Medal", "5", "Bronze Medal", "Silver Medal", "4"}
6. 返回结果:
最终的 ans
数组返回的是每位运动员的获奖情况。
总结:
通过将运动员的得分和索引打包成 pair
,并将分数取负以便排序,再根据排序后的结果分配奖牌或名次编号,程序解决了运动员排名的问题。
用sort来对分数进行从大到小排序,这里比较巧妙的是将分数取负数,这样能够得到,因为sort是从小到大来排的,这样就讲大一点的数排在了前面。然后根据pair中的对应的索引来分配字符串。小于3的给字符串。字符串提前写好在了函数中.
最后将排好序的数组arr依次取出索引,将索引给一个新的字符串数组完成赋值
如何创建字符串?
cpp
string desc[3] = {"Gold Medal", "Silver Medal", "Bronze Medal"};
这里还有一个函数用法。emplace_back
将什么插入在后方?
循环的执行过程如下:
当 i = 0,arr.emplace_back(make_pair(-50, 0)),此时 arr 中有 (-50, 0)。
当 i = 1,arr.emplace_back(make_pair(-80, 1)),此时 arr 中有 (-50, 0), (-80, 1)。
当 i = 2,arr.emplace_back(make_pair(-70, 2)),此时 arr 中有 (-50, 0), (-80, 1), (-70, 2)。
arr 是一个 pair 的动态数组,用来保存每个运动员的分数及其对应的索引。