游戏中排名第三大分数
题面
小M想要通过査看往届游戏比赛的排名来确定自己比赛的目标分数。
他希望找到往届比赛中排名第三的分数,作为自己的目标。
具体规则如下:
1.如果分数中有三个或以上不同的分数,返回其中第三大的分数。
2.如果不同的分数只有两个或更少,那么小M将选择最大的分数作为他的目标。
分析
显然这是一个非常简单的题,但是我的初步实现非常臃杂而丑陋;
我们先将所有的分数排序,由于分数一致的值在一起,很容易就能统计出有多少不同的数,其后分类讨论有多少个不同的分数即可,多于等于三个的从头开始找第三大的,否则返回最大的即可。
思路还算清晰,但是实现起来先要 sort,然后还要再遍历一遍所有数并进行统计,实在是不优雅,一时起意想看看豆包的 MarsCode AI 有什么独到的见解,结果 AI 给出的方法真的是惊艳到我了(不然我也不会用这么简单的题写一篇没什么思维含量的笔记是吧):
#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
using namespace std;
int solution(int n, std::vector<int> nums) {
// 使用集合存储不同的分数
std::set<int> unique_scores(nums.begin(), nums.end());
// 如果集合的大小小于3,返回最大的分数
if (unique_scores.size() < 3) {
return *unique_scores.rbegin(); // 返回最大的分数
}
// 否则,找到第三大的分数
auto it = unique_scores.rbegin();
std::advance(it, 2); // 移动到第三大的元素
return *it;
}
int main() {
std::cout << (solution(3, {3, 2, 1}) == 1) << std::endl;
std::cout << (solution(2, {1, 2}) == 2) << std::endl;
std::cout << (solution(4, {2, 2, 3, 1}) == 1) << std::endl;
return 0;
}
对于这段代码。豆包 AI 给出了很清晰的解释:
std::set<int> unique_scores(nums.begin(), nums.end()); :
这行代码使用 `nums` 数组的范围 `[nums.begin(), nums.end())` 来初始化集合 `unique_scores`。
- 初始化过程中,`std::set` 会自动去除重复的元素,并且将剩余的元素按升序排列。
这段代码不仅巧妙运用了 std::set 的特性,还使用了指针迭代器来进一步优化代码,实在优雅。
思考
尽管这道题十分简单,但是见微知著,简单的题一样有巧思与优雅的解法。而事实上,难题不也是由一个个简单的小问题组成的大问题吗,如果小问题我们能解决的很好,就相当于地基打的好,再去解决大问题,肯定可以更加得心应手。
std::set 的特性很明显,指针迭代器也是非常常见的东西,如此基础且底层的东西,我没有想到用来简化优雅我的代码,事实上,无论在小或大,易或难的事情上,我们总可能忽略一些看似底层的东西,而利用 AI 我们仍可以在解决高深的问题时侧面补充一些以前没有注意到的短板,好比本题提到的优化方式,好比爱因斯坦用水测量电灯泡容积的故事。