IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 力扣练习——18 前 K 个高频元素 -> 正文阅读

[数据结构与算法]力扣练习——18 前 K 个高频元素

18 前 K 个高频元素

1.问题描述
给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2

输出: [1,2]

示例 2:

输入: nums = [1], k = 1

输出: [1]

说明:

你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。

你的算法的时间复杂度必须优于 O(n log n) , n 是数组的大小。

题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。

输出时,首先输出频率最高的元素,如果频率相同,则先输出元素值较大的元素。

可使用以下main函数:

int main()

{

int n,data,k;

vector<int> nums;

cin>>n;

for(int i=0; i<n; i++)

{

    cin>>data;

    nums.push_back(data);

}

cin>>k;

vector<int> res=Solution().topKFrequent(nums,k);

for(int i=0; i<res.size(); i++)

{

    if (i>0)

        cout<<" ";

    cout<<res[i];

}

return 0;

}

2.输入说明
首先输入nums数组的长度n,

然后输入n个整数,以空格分隔。

最后输入k。
3.输出说明
首先输出频率最高的元素,如果频率相同,则先输出元素值较大的元素。

元素之间以空格分隔。
4.范例
输入
8
1 1 1 2 2 3 3 4
3
输出
1 3 2
5.代码

#include<iostream>
#include<queue>
#include<algorithm>
#include<map>
using namespace std;

class Solution {
public:
	vector<int> topKFrequent(vector<int>& nums, int k) {
		
		map<int, int> map;//注意map的用法
		for(int i:nums)//迭代遍历nums中元素并放入map中  ,注意 i用来代表nums中的每个元素
			map[i] ++; 

		//优先级队列实现最小堆算法
		//1.优先队列没有front()函数与 back()函数,而只能通过top()函数来访问队首元素(也可以称为堆顶元素),也就是优先级最高的元素。
		//2.priority_queue又称为优先队列,其底层是用堆来进行实现的。在优先队列中,队首元素一定是当前队列中优先级最高的那一个。
		//第二个参数vector<>是用来承载底层数据结构堆(heap)的容器;
		//第三个参数less<>或者greater<>是对第一个参数的比较类,less<int>表示数字越大优先级越大,greater<int>表示数字越小,优先级越大。
		//3.关于vector< pair<int, int> >用法:类似于map,但map会对插入的元素按键自动排序,而且不允许键重复。vector的这种用法不会自动排序,而且允许重复。
		
		priority_queue< pair<int, int>, vector< pair<int, int> >, greater< pair<int, int> > > Q; 
		//其中greater< pair<int,int> >会在first相等时比较second

		// 遍历map,维护一个大小为K的小顶堆
		for (auto it : map)//c++11以后用aoto遍历map
			if (Q.size() == k)
			{ //队列满了,替换头元素,重新排序堆
				if (it.second > Q.top().first)//it指代map中元素,it.second指向频率;而Q.top().first指向堆顶元素的频率大小
				{ //堆排
					Q.pop();
					Q.push(make_pair(it.second, it.first));//先根据元素出现频率排序,再根据元素大小排序
				}
			}
			else//小于K直接插入
				Q.push(make_pair(it.second, it.first));//这边插入时,pair<频率,元素值> 
		vector<int> res;
		while (Q.size()) { //将优先队列中k个高频元素存入vector
			res.push_back(Q.top().second);//注意,这边second指向元素值
			Q.pop();
		}
		return vector<int>(res.rbegin(), res.rend());//反向迭代器 ,思考下为什么?解答:因为小顶堆是堆顶元素一个个弹出来的,
		                                             //也就是前K个中频率最低的那个元素,先进入到res中,所以最后的结果肯定要逆序输出!
	}

};



int main()

{

	int n, data, k;

	vector<int> nums;

	cin >> n;

	for (int i = 0; i < n; i++)

	{

		cin >> data;

		nums.push_back(data);

	}

	cin >> k;

	vector<int> res =Solution().topKFrequent(nums, k);

	for (int i = 0; i < res.size(); i++)

	{

		if (i > 0)

			cout << " ";

		cout << res[i];

	}

	return 0;

}
  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:48:39  更:2022-07-17 16:52:30 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 23:51:02-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码