题目链接
题目描述
问题描述
- 给定一个长度为n的整型数组,已知其中一个数字的出现次数超过数组长度的一半,找出这个元素
输入格式
- 一个长度为n的数组,其中某个元素的出现次数大于n/2
输出格式
- 一个整数
输入样例
- [1,3,8,2,3,1,3,3,3]
输出样例
- 3
数据范围
- 任意长度为n整数数组,其中某个元素的出现次数大于n/2
题目思路
基础思路
题目要求我们统计每种数字出现的次数,并找出出现次数大于一半的数字个数,也就是说,我们要找到出现次数最多的数字,因为只要这个数字出现次数大于整体数字的一半,那么他就是出现次数最多的数字。
我们可以建立一个哈希表,来存储每个数字出现的个数。最后遍历哈希数组,找到出现次数最多的数字的下标,然后返回就好。
进阶思路
我们可以利用sort的特性来直接输出最多出现的数字个数,只需要稍微设计一下结构体的形式就好
我们还需要统计数字出现的个数,这个少不了。
题解代码
#include <bits/stdc++.h>
using namespace std;
int solution(vector<int> array) {
// 搜索到最大的数字,便于确定计数数组的大小
int n = *max_element(array.begin(), array.end())+1;
// 计数数组,记录每个数字出现的次数,初始值为0
vector<int> cnt(n, 0);
// 遍历数组,统计每个数字出现的次数,并更新计数数组
for(int i = 0;i<array.size();i++) {
cnt[array[i]]++;
}
// 遍历计数数组,找到出现次数最多的数字,ans即为众数
int ans = 0;
for(int i = 0;i<n;i++) {
// 如果当前数字出现的次数大于ans出现的次数,更新ans
// 注意,这里使用了计数数组的下标,即数字本身作为计数数组的下标
if(cnt[i] > cnt[ans]) ans = i;
}
// 返回众数
return ans;
}
int main() {
// Add your test cases here
cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
return 0;
}
进阶代码
#include <bits/stdc++.h>
using namespace std;
// 设计结构体,用于优先队列排序
struct ttt
{
int times;
int num;
};
int solution(vector<int> array) {
// 统计每个数字出现的次数,
map<int,int> m;
// 遍历数组,统计每个数字出现的次数
for(auto i : array)m[i]++;
// 定义优先队列,用于排序,按照出现次数从大到小排序
priority_queue<ttt,vector<ttt>,less<>> q;
// 遍历map,将每个数字出现的次数和数字放入优先队列中
for(auto i : m)q.push({i.second,i.first});
// 返回出现次数最多的数字
// 注意这里不要使用q.top().times,因为我们要返回的是数字,而不是出现次数
return q.top().num;
}
int main() {
// Add your test cases here
cout << (solution({1, 3, 8, 2, 3, 1, 3, 3, 3}) == 3) << endl;
return 0;
}
反思
一道很简单的思路题,做出来不难,重点是如何更好地利用数据结构来解决这个问题,因为这个问题足够简单,所以解决问题就不重要了,重要的是,怎么帅气的解决问题