LeetCode 算法:前 K 个高频元素 c++
原题链接🔗:前 K 个高频元素
难度:中等⭐️⭐️
题目
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
提示:
- 1 <= nums.length <= 105
- k 的取值范围是 [1, 数组中不相同的元素的个数]
- 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的
进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。
堆
堆(Heap)是一种特殊的树状数据结构,它满足两个主要特性:
结构性:堆通常是一棵完全二叉树,这意味着除了最后一层外,其他每一层都被完全填满,并且最后一层的节点尽可能地集中在左侧。
堆属性:堆中的每一个节点都必须满足特定的顺序要求,这个要求可以是最大堆属性或最小堆属性。
- 最大堆:任何一个父节点的值都大于或等于它的子节点的值。这意味着堆的根节点是所有节点中的最大值。
- 最小堆:任何一个父节点的值都小于或等于它的子节点的值。这意味着堆的根节点是所有节点中的最小值。
堆在计算机科学中广泛应用于各种算法和数据结构,特别是在需要快速访问最大元素或最小元素的场景中。例如,堆排序算法、优先队列的实现等。
在编程语言中,堆通常通过优先队列(Priority Queue)这种抽象数据类型来实现。优先队列允许快速地插入新元素和删除(或检索)最大(或最小)元素。
堆的常见操作包括:
- 插入(Push):向堆中添加一个新元素。
- 删除最大/最小元素(Pop):移除并返回堆中的最大(或最小)元素。
- 查找最大/最小元素(Peek/Top):返回堆中的最大(或最小)元素,但不从堆中移除它。
堆的实现可以通过数组来完成,其中每个元素的索引和其父节点或子节点的索引之间有一定的数学关系。例如,在数组表示的堆中,一个元素的父节点可以通过
(i-1)/2计算得到,其中i是该元素的索引;其子节点可以通过2*i + 1(左子节点)和2*i + 2(右子节点)计算得到。
题解
- 解题思路:
"数组中的第K个最大元素"是LeetCode上的一道经典题目,它要求在给定的未排序数组中找到第K个最大的元素。以下是解题的几种思路:
- 排序
- 思路:首先对数组进行排序,然后直接访问数组的倒数第K个位置的元素。
- 复杂度:时间复杂度为O(n log n),空间复杂度为O(1)(如果使用原地排序算法)。
- 快速选择(Quick Select)
- 思路:这是快速排序算法的变种。选择一个"枢纽"(pivot)元素,将数组分为两部分:一部分包含比枢纽小的元素,另一部分包含比枢纽大的元素。然后根据枢纽的位置来决定是继续在左侧还是右侧搜索第K个最大元素。
- 复杂度:平均时间复杂度为O(n),最坏情况(已排序数组)为O(n^2)。
- 堆(优先队列)
- 思路:
- 使用最小堆:维护一个大小为K的最小堆,遍历数组,对于每个元素,如果堆未满,则直接加入;如果堆满了且当前元素大于堆顶元素,则替换堆顶元素。
- 使用最大堆:维护一个大小为n的堆,遍历数组,对于每个元素,如果堆未满,则直接加入;如果堆满了且当前元素小于堆顶元素,则不加入。最后,堆顶元素是第K大的元素,但这种方法需要O(n)空间。
- 复杂度:时间复杂度为O(n log K),空间复杂度为O(K)。
- BFPRT算法(中位数的中位数算法)
- 思路:这是一种选择算法,用于找到未排序数组的第K小(或第K大)元素。它首先找到一组“候选”元素,然后递归地在这组候选元素中找到中位数,直到找到第K小的元素。
- 复杂度:平均时间复杂度为O(n)。
- 线性时间选择算法
- 思路:这是一种基于随机化的算法,通过随机选择枢纽元素来减少最坏情况的发生概率。
- 复杂度:期望时间复杂度为O(n)。
- c++ demo:
#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>// 自定义比较函数,首先按频率降序,频率相同则按元素值升序
bool compare(const std::pair<int, int>& a, const std::pair<int, int>& b) {if (a.second == b.second) {return a.first < b.first;}return a.second > b.second;
}std::vector<int> topKFrequent(const std::vector<int>& nums, int k) {std::unordered_map<int, int> freqMap;for (int num : nums) {freqMap[num]++;}std::vector<std::pair<int, int>> freqList;for (const auto& kv : freqMap) {freqList.emplace_back(kv.first, kv.second);}// 根据频率和元素值排序std::sort(freqList.begin(), freqList.end(), compare);// 选择前 K 个元素std::vector<int> result;for (int i = 0; i < k; ++i) {result.push_back(freqList[i].first);}return result;
}int main() {std::vector<int> nums = { 1, 1, 1, 2, 2, 3 };int k = 2;std::vector<int> result = topKFrequent(nums, k);std::cout << "The " << k << " most frequent elements are: ";for (int num : result) {std::cout << num << " ";}std::cout << std::endl;return 0;
}
- 输出结果:
The 2 most frequent elements are: 1 2
- 代码仓库地址:topKFrequent
相关文章:
LeetCode 算法:前 K 个高频元素 c++
原题链接🔗:前 K 个高频元素 难度:中等⭐️⭐️ 题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums [1,1,1,2,2,3], k 2 输出: [1,2] 示例 2…...
MySQL的SQL语句更新某个字段的值在原来值的基础上随机增加100~600
要在 MySQL 中更新某个字段的值,使其在原有值的基础上随机增加一个 100 到 600 之间的值,你可以使用 RAND() 函数来生成随机数,并结合其他 SQL 函数进行计算。以下是一个 SQL 更新语句的示例: UPDATE your_table_name SET your…...
LeetCode --- 410周赛
题目列表 3248. 矩阵中的蛇 3249. 统计好节点的数目 3250. 单调数组对的数目 I 3251. 单调数组对的数目 II 一、矩阵中的蛇 只要按照题目要求模拟即可,代码如下 class Solution { public:int finalPositionOfSnake(int n, vector<string>& commands…...
最佳的iPhone解锁软件和应用程序
在探讨最佳的iPhone解锁软件和应用程序时,我们需要考虑多个方面,包括软件的解锁能力、易用性、安全性、兼容性以及用户评价等。以下是对当前市场上几款优秀iPhone解锁软件和应用程序的详细分析,旨在为用户提供全面而深入的指导。 一、奇客iO…...
初等函数和它的表达式
常量函数,幂函数,指数函数,对数函数,三角函数和反三角函数成为基本初等函数。基本初等函数经过有限四则运算和符合运算得到的函数称为初等函数。 1. 常量函数 表达式: (其中 c 是常数)参数的意…...
Android 12系统源码_多屏幕(二)模拟辅助设备功能开关实现原理
前言 上一篇我们通过为Android系统开启模拟辅助设备功能开关,最终实现了将一个Activity显示到多个屏幕的效果。 本篇文章我们具体来分析一下当我们开启模拟辅助设备功能开关的时候,Android系统做了什么哪些操作。 一、模拟辅助设备功能开关应用位置 …...
【Go语言初探】(二)、项目文件结构和GOPATH设置
一、go语言项目文件结构 由go/bin、go/src和go/pkg三个子文件夹组成,见下图: 实际项目: 二、gopath路径变量设置 在项目中创建main.go文件后,IDE会提示设置GOPATH路径: 点击“configure GOPATH”,设置GOP…...
三种简单排序:插入排序、冒泡排序与选择排序 【算法 05】
三种简单排序:插入排序、冒泡排序与选择排序 在编程中,排序算法是基础且重要的知识点。虽然在实际开发中,我们可能会直接使用标准库中的排序函数(如C的std::sort),但了解并实现这些基础排序算法对于理解算法…...
Python -- GUI图形界面编程—GUI编程实例 博主也在持续学习中[ 持续更新中!!! 欢迎白嫖 也求粉啊啊啊~ ]
本文介绍了GUI的图形界面编程(相关视频是哔站上的应该搜这个题目就能找到),文章还是很基础的,反正我是小白从0开始,主要的结构tinkter库、重要组件简介(这个不用死记硬背 用的时候再说)、Label&…...
Vue2和Vue3中的diff算法
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、diff算法是什么?二、vue2中的diff算法三、vue3中的diff算法总结 前言 一、diff算法是什么? diff算法很早就存在了,一开…...
springboot使用aop或Jackson进行数据脱敏
1.aop 启动类加EnableAspectJAutoProxy 自定义注解,在实体类中使用表示被脱敏字段 建立aop切面类 可能这里gpt会建议你用Pointcut("execution(public * com.xx.aop..*.get*(..))")这种方式拦截,这种我试了,拦截不住。猜测在mvc返…...
【Solidity】基础介绍
数据类型 值类型 值类型的变量在赋值或作为函数参数传递时会被复制。 布尔类型:bool整数类型: 无符号:uint8、uint16、…、uint256 (uint256 可简写为 uint)有符号:int8、int16、…、int256 (int256可简写为 int) 地址类型&…...
【SpringBoot3】双向实时通讯 websocket
文章目录 一、Websocket使用步骤二、示例1:继承抽象类 AbstractWebSocketHandler后端代码前端代码 三、示例2:使用注解ServerEndpoint后端代码前端代码 四、前端代码封装 一、Websocket使用步骤 在Spring Boot中使用WebSocket是一个常见的需求ÿ…...
搭建内网开发环境(一)|基于docker快速部署开发环境
引言 最近因需要搭建一套简易版的纯内网的开发环境,服务器采用 centos8.0,容器化技术采用 docker 使用 docker-compose 进行容器编排。 该系列教程分为两大类: 软件安装和使用,这类是开发环境常用的软件部署和使用,涉…...
MATLAB R2023b配置Fortran编译器
MATLAB R2023b配置Fortran编译器 引言1. 安装Visual Studio 20192. 安装Intel API20243. 配置xml文件文件4. 设置环境变量5. MATLAB编译Fortran 引言 当我们需要用到MATLAB编译Fortran代码后进行调用计算时,整个配置流程较繁琐。下面以MATLAB R2023b为例࿰…...
2024新型数字政府综合解决方案(七)
新型数字政府综合解决方案通过集成人工智能、大数据、区块链和云计算技术,创建了一个高度智能化和互联互通的政府服务平台,旨在全面提升行政效率、服务质量和透明度。该平台实现了跨部门的数据整合与实时共享,利用人工智能进行智能决策支持和…...
搭建高可用k8s集群
高可用 Kubernetes V1.28.10 安装 文章目录 1. 环境介绍2. 准备工作2.1 修改主机名称2.2 修改hosts文件2.3 关闭防火墙和SLinux2.4 配置SSH免密访问2.4.1 主机名称: k8s-master-01 操作 2.5 配置yum源2.6 禁用Swarp分区2.7 同步时间2.8 配置内核转发及网桥过滤2.9 安装 IPVS 3…...
完美解决html2canvas + jsPDF导出pdf分页内容截断问题
代码地址:https://github.com/HFQ12333/export-pdf.git html2canvas jspdf方案是前端实现页面打印的一种常用方案,但是在实践过程中,遇到的最大问题就是分页截断的问题:当页面元素超过一页A4纸的时候,连续的页面就会…...
14 地址映射
14 地址映射 1、地址划分2、相关函数2.1 ioremap/iounmap2.2 mmap地址映射 3、总结 1、地址划分 明确:在linux系统中,不管是应用程序还是驱动程序,都不允许直接访问外设的物理地址,要想访问必须将物理地址映射到用户虚拟地址或者内核虚拟地址࿰…...
Java Resilience4j-RateLimiter学习
一. 介绍 Resilience4j-RateLimiter 是 Resilience4j 中的一个限流模块,我们对 Resilience4j 的 CircuitBreaker、Retry 已经有了一定的了解,现在来学习 RateLimiter 限流器; 引入依赖; <dependency><groupId>io.g…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
GitHub 趋势日报 (2025年06月08日)
📊 由 TrendForge 系统生成 | 🌐 https://trendforge.devlive.org/ 🌐 本日报中的项目描述已自动翻译为中文 📈 今日获星趋势图 今日获星趋势图 884 cognee 566 dify 414 HumanSystemOptimization 414 omni-tools 321 note-gen …...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南
文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
