游戏排名第三大的分数——题目解析及解题

150 阅读3分钟

问题描述

小M面临的问题是,给定一个分数数组,他需要确定自己的目标分数。规则如下:

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

解题思路

为了解决这个问题,我们可以采用以下步骤:

  1. 使用一个集合(std::set)来存储数组中的不同分数,因为集合会自动去除重复的元素。
  2. 检查集合中元素的数量,如果少于3个,则直接返回最大的分数。
  3. 如果集合中的元素数量大于等于3个,我们将集合转换为一个向量(std::vector),并对它进行排序,以便找到第三大的分数。
  4. 返回排序后的第三大分数。

代码解析

下面是一个C++语言的实现,我们将逐步解析代码中的每个部分。

#include <algorithm>
#include <iostream>
#include <set>
#include <string>
#include <vector>

using namespace std;

int solution(int n, vector<int> nums) {
  // 使用集合存储不同的分数
  set<int> scores(nums.begin(), nums.end());
  
  // 如果集合中的元素少于3个,返回最大的分数
  if (scores.size() < 3) {
    return *scores.rbegin(); // rbegin() 返回反向迭代器,指向最大元素
  } else {
    // 将集合转换为向量
    vector<int> _scores(scores.begin(), scores.end());
    // 对向量进行排序
    sort(_scores.begin(), _scores.end());
    // 返回第三大的分数
    return _scores[_scores.size() - 3];
  }
}

int main() {
  // 测试样例
  cout << (solution(3, {3, 2, 1}) == 1) << endl;
  cout << (solution(2, {1, 2}) == 2) << endl;
  cout << (solution(4, {2, 2, 3, 1}) == 1) << endl;
  return 0;
}

容器的常用操作和函数详解

在上述代码中,我们使用了两种容器:std::setstd::vector。以下是这些容器的常用操作和函数的详解:

set

std::set 是一个基于红黑树的有序容器,它能够存储唯一的元素,并自动按照升序排列。

  • 插入操作insert(value) 向集合中插入一个值。如果值已存在,则不会插入。
  • 删除操作erase(value) 从集合中删除一个值。如果值不存在,则不做任何操作。
  • 查找操作find(value) 查找一个值。如果找到了,返回指向该元素的迭代器;如果没有找到,返回指向end()的迭代器。
  • 大小操作size() 返回集合中元素的数量。
  • 清空操作clear() 移除集合中的所有元素。
  • 反向迭代器rbegin()rend() 分别返回指向最大元素和最小元素的反向迭代器。

vector

std::vector 是一个动态数组,可以根据需要自动调整大小。

  • 访问元素:使用 operator[]at() 访问元素。at() 在越界时会抛出异常。
  • 插入操作push_back(value) 在向量末尾添加一个元素。
  • 删除操作pop_back() 删除向量末尾的元素。erase(iterator) 删除指定位置的元素。
  • 大小操作size() 返回向量中元素的数量。resize(new_size) 改变向量的大小。
  • 清空操作clear() 移除向量中的所有元素。
  • 容量操作capacity() 返回向量分配的存储空间大小。reserve(new_cap) 改变向量的存储容量。

std::sort

std::sort 是一个非常强大的排序函数,它可以接受自定义的比较函数,并且可以对任意类型的迭代器进行排序。

  • 基本用法sort(begin, end) 对指定范围内的元素进行排序。
  • 自定义比较sort(begin, end, compare) 使用自定义比较函数进行排序。

示例代码

以下是一些操作的示例代码:

#include <vector>
#include <set>
#include <algorithm>
#include <iostream>

int main() {
    std::vector<int> vec = {5, 3, 9, 1};
    std::set<int> s;

    // 向量操作
    vec.push_back(10); // 在向量末尾添加元素
    vec.erase(vec.begin() + 1); // 删除第二个元素
    std::cout << "Vector size: " << vec.size() << std::endl; // 输出向量大小
    vec.resize(3); // 改变向量大小为3

    // 集合操作
    s.insert(5); // 插入元素
    s.erase(3); // 删除元素,如果不存在则不做操作
    std::cout << "Set size: " << s.size() << std::endl; // 输出集合大小
    s.clear(); // 清空集合

    // 排序操作
    std::sort(vec.begin(), vec.end()); // 对向量进行排序
    for (int i : vec) {
        std::cout << i << " "; // 输出排序后的向量
    }
    std::cout << std::endl;

    return 0;
}