代码解析:游戏排名第三大的分数 | 豆包MarsCode AI刷题

60 阅读4分钟

代码解析:游戏排名第三大的分数

题目回顾

小M想要通过查看往届游戏比赛的排名来确定自己比赛的目标分数。他希望找到往届比赛中排名第三的分数,作为自己的目标。具体规则如下:

  1. 如果分数中有三个或以上不同的分数,返回其中第三大的分数。
  2. 如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。

思路与设计

  1. 数据去重

    • 由于题目要求处理的是不同的分数,因此首先需要去除输入分数数组中的重复项。
    • 使用std::set数据结构可以有效地去除重复项,因为set内部自动进行排序且不允许重复元素。
  2. 分数排序

    • 为了找到第三大的分数,需要对去重后的分数进行排序。
    • 由于set已经自动排序,我们可以直接将set转换为vector,但需要注意set默认是升序排序的,而我们需要的是降序排序。
    • 因此,在转换为vector后,使用std::sort函数进行降序排序。
  3. 结果选择

    • 根据排序后的分数数量,如果数量大于等于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];

	    }

	}

图解与步骤说明

  1. 输入与初始化

    • 输入:分数数组nums和数组长度n(虽然n在代码中未直接使用,但可以作为输入验证的一部分)。
    • 初始化:创建空的set<int>vector<int>
  2. 去重

    • 将分数数组nums的元素插入到set<int>中,自动去除重复项并排序。
  3. 排序

    • set<int>转换为vector<int>
    • 使用std::sort函数对vector<int>进行降序排序。
  4. 结果选择

    • 判断vector<int>的大小(即去重后的分数数量)。
    • 如果大小大于等于3,返回排序后数组的第二个元素(第三大的分数)。
    • 如果大小小于3,返回排序后数组的第一个元素(最大的分数)。
  5. 输出

    • main函数中,通过比较函数返回值与预期结果来验证正确性。
    • 输出1(true)或0(false)表示测试是否通过。

总结

本题通过std::setstd::vector的结合使用,有效地解决了去重和排序的问题。通过简单的条件判断,根据分数数量返回了正确的结果。该方法具有清晰的思路、简洁的代码和良好的性能表现。在时间复杂度和空间复杂度方面均达到了较优的水平。通过本题的练习,可以加深对setvector等数据结构以及排序算法的理解和应用。