506.相对名次

目录

题目

给你一个长度为 n 的整数数组 score ,其中 scorei 是第 i 位运动员在比赛中的得分。所有得分都 互不相同 。

运动员将根据得分 决定名次 ,其中名次第 1 的运动员得分最高,名次第 2 的运动员得分第 2 高,依此类推。运动员的名次决定了他们的获奖情况:

名次第 1 的运动员获金牌 "Gold Medal" 。

名次第 2 的运动员获银牌 "Silver Medal" 。

名次第 3 的运动员获铜牌 "Bronze Medal" 。

从名次第 4 到第 n 的运动员,只能获得他们的名次编号(即,名次第 x 的运动员获得编号 "x")。

使用长度为 n 的数组 answer 返回获奖,其中 answeri 是第 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 的动态数组,用来保存每个运动员的分数及其对应的索引。

相关推荐
yi0111 小时前
DAY28: LeetCode 111. 二叉树的最小深度
人工智能·笔记·python·算法·leetcode·二叉树·递归
wuyk5551 小时前
27.LeetCode 2265. 统计值等于子树平均值的节点数 —— 后序遍历实战
stm32·单片机·嵌入式硬件·算法
xiangyun612 小时前
C++ list 模拟实现(二):const迭代器与反向迭代器,模板的黑魔法
开发语言·数据库·c++·算法·stl·list
xxwl5852 小时前
三、区域赛算法模版第三章---字符串相关算法
笔记·学习·算法
信奥卷王2 小时前
[GESP202509 六级] 划分字符串(含视频)
数据结构·算法
酒醉的胡铁2 小时前
相似度搜索的常见算法
算法·ai
局部有解2 小时前
Leetcode Hot100 - 最长连续序列
算法·leetcode·职场和发展
m0_752035632 小时前
Redis 数据结构总结
数据结构·数据库·redis
行者全栈架构师3 小时前
给开源 Rust 工具加一个新检查项,TRAE 帮我从想法跑到构建产物:全链路实战
前端·算法·架构
tachibana23 小时前
Go 语言的 Map 是否是并发安全的?
开发语言·数据结构·后端·golang·go·语言