代码解析:游戏排名第三大的分数
题目回顾
小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下:
- 如果分数中有三个或以上不同的分数,返回其中第三大的分数。
- 如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。
思路与设计
-
数据去重:
- 由于题目要求处理的是不同的分数,因此首先需要去除输入分数数组中的重复项。
- 使用
std::set数据结构可以有效地去除重复项,因为set内部自动进行排序且不允许重复元素。
-
分数排序:
- 为了找到第三大的分数,需要对去重后的分数进行排序。
- 由于
set已经自动排序,我们可以直接将set转换为vector,但需要注意set默认是升序排序的,而我们需要的是降序排序。 - 因此,在转换为
vector后,使用std::sort函数进行降序排序。
-
结果选择:
- 根据排序后的分数数量,如果数量大于等于3,则返回第三大的分数(即排序后数组的第二个元素,因为数组索引从0开始)。
- 如果数量小于3,则返回最大的分数(即排序后数组的第一个元素)。
数据结构与算法
-
数据结构:
std::set<int>:用于去重和初步排序。std::vector<int>:用于存储去重并排序后的分数。
-
算法:
- 去除重复分数:利用
set的自动去重和排序特性。 - 分数排序:使用
std::sort函数对vector进行降序排序。 - 结果选择:根据分数数量返回相应的分数。
- 去除重复分数:利用
时间复杂度与空间复杂度
-
时间复杂度:
- 去重和初步排序(由
set完成):O(n log n),其中n是输入分数数组的长度。 - 将
set转换为vector:O(n)。 - 对
vector进行降序排序:O(n log n)。 - 结果选择:O(1)。
- 总时间复杂度:O(n log n)。
- 去重和初步排序(由
-
空间复杂度:
set存储去重后的分数:O(m),其中m是去重后的分数数量。vector存储排序后的分数:O(m)。- 总空间复杂度:O(m)。
代码详解
cpp复制代码
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
// 函数声明
int solution(int n, std::vector<int> nums);
// 主函数
int main() {
// 测试样例1
cout << (solution(3, {3, 2, 1}) == 1) << endl; // 输出: 1 (true)
// 测试样例2
cout << (solution(2, {1, 2}) == 2) << endl; // 输出: 1 (true)
// 测试样例3
cout << (solution(4, {2, 2, 3, 1}) == 1) << endl; // 输出: 1 (true)
// 可以添加更多测试样例进行验证
return 0;
}
// 函数定义
int solution(int n, std::vector<int> nums) {
// 使用set去重
set<int> uniqueScores(nums.begin(), nums.end());
// 将set转换回vector并排序
vector<int> sortedScores(uniqueScores.begin(), uniqueScores.end());
// 注意:set默认是升序排序的,我们需要降序排序,所以使用rbegin()和rend()
sort(sortedScores.rbegin(), sortedScores.rend());
// 根据不同分数的数量返回相应的分数
if (sortedScores.size() >= 3) {
// 如果分数数量大于等于3,返回第三大的分数(排序后数组的第二个元素)
return sortedScores[2];
} else {
// 如果分数数量小于3,返回最大的分数(排序后数组的第一个元素)
return sortedScores[0];
}
}
图解与步骤说明
-
输入与初始化:
- 输入:分数数组
nums和数组长度n(虽然n在代码中未直接使用,但可以作为输入验证的一部分)。 - 初始化:创建空的
set<int>和vector<int>。
- 输入:分数数组
-
去重:
- 将分数数组
nums的元素插入到set<int>中,自动去除重复项并排序。
- 将分数数组
-
排序:
- 将
set<int>转换为vector<int>。 - 使用
std::sort函数对vector<int>进行降序排序。
- 将
-
结果选择:
- 判断
vector<int>的大小(即去重后的分数数量)。 - 如果大小大于等于3,返回排序后数组的第二个元素(第三大的分数)。
- 如果大小小于3,返回排序后数组的第一个元素(最大的分数)。
- 判断
-
输出:
- 在
main函数中,通过比较函数返回值与预期结果来验证正确性。 - 输出
1(true)或0(false)表示测试是否通过。
- 在
总结
本题通过std::set和std::vector的结合使用,有效地解决了去重和排序的问题。通过简单的条件判断,根据分数数量返回了正确的结果。该方法具有清晰的思路、简洁的代码和良好的性能表现。在时间复杂度和空间复杂度方面均达到了较优的水平。通过本题的练习,可以加深对set和vector等数据结构以及排序算法的理解和应用。