当前位置: 首页 > news >正文

算法-每日一题(DAY18)多数元素

1.题目链接

169. 多数元素 - 力扣(LeetCode)

2.题目描述

给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入:nums = [3,2,3]
输出:3

示例 2:

输入:nums = [2,2,1,1,1,2,2]
输出:2

提示:

n == nums.length
1 <= n <= 5 * 10^4
-109 <= nums[i] <= 10^9

3.解题思路

为了追求效率,让时间复杂度和空间复杂度都保持在最低,我们使用摩尔投票算法来实现这道题。

摩尔投票算法是一种用于在一个数组中找出出现次数超过一半的元素(即众数)的算法,核心思路就是通过 “抵消” 不同元素的出现次数,最终剩下的元素就是多数元素,因为多数元素的出现次数超过数组长度的一半,所以无论其他元素如何抵消,最终剩下的一定是多数元素。

这道题要求返回该数组中的最多元素,也就是众数,我们使用一个候选元素和一个计数器来找出数组中的众数。首先,定义一个变量 num 作为候选众数,初始值为0;再定义一个变量 cnt 来记录候选元素的票数,初始值为0。接下来,我们通过遍历数组 nums 中的每个元素 x。如果 cnt 为0,说明当前没有有效的候选元素,那么我们将 x 作为新的候选众数,且将 cnt 设为1。若 x 等于当前的候选元素 num,则票数 cnt 增加1,表明该元素得到更多支持;若 x 与候选元素不同,则票数 cnt 减少1,表明候选元素的支持度下降。最终,当遍历完成时,num 即为数组中的众数。

通过这种方式,我们只需要遍历一次数组,通过巧妙地更新候选元素和票数,能够在 O(n) 的时间复杂度内找出数组中出现次数超过一半的元素。

4.题解代码

class Solution {
public:int majorityElement(vector<int>& nums) {int num = 0;//定义一个变量num,用于存储候选中的众数int cnt = 0;//定义一个变量cnt,用于储存候选元素的票数(出现次数)for (int x : nums)//循环,依次取出数组nums中的变量,赋给x{if (cnt == 0)//如果此时候选元素票数为0,那么更新候选元素为当前元素{num = x;//将当前元素的值赋给候选元素cnt++;//让候选元素票数+1}else if (x = num)//如果候选元素和当前遍历的元素相同{cnt++;//那么就让候选元素得票数+1}else//如果候选元素和当前遍历的元素不同{cnt--;//那么就让候选元素得票数-1}}return num;//最终返回num的值,即为该数组中的最多元素}
};

5.示例演算

步骤遍历的元素 x条件判断num(候选元素)cnt(计数)说明
初始00初始状态
12cnt == 0 成立21首次遇到元素,设为候选
22x == num(2 == 2)22相同元素,计数 + 1
31x != num(1 != 2)21不同元素,计数 - 1
41x != num(1 != 2)20不同元素,计数 - 1(抵消)
51cnt == 0 成立11计数为 0,更换候选为 1
62x != num(2 != 1)10不同元素,计数 - 1(抵消)
72cnt == 0 成立21计数为 0,更换候选为 2
结束循环结束21返回最终候选元素 2


6.复杂度计算

时间复杂度:只将数组中的元素遍历一次,故时间复杂度为O(n)

空间复杂度:只使用了常数空间来储存变量,没有使用额外空间,故时间复杂度为O(1)

7.拓展:哈希表法和排序法

哈希表法

我们使用一个哈希表 counts 来记录每个数字的出现次数。首先,初始化 majority 变量为0,表示当前的候选众数,同时初始化 cnt 为0,表示当前候选众数的出现次数。然后,我们遍历数组 nums 中的每一个元素 num。对于每个元素,首先更新哈希表中该元素的出现次数 counts[num]。接着,我们判断当前元素的出现次数是否大于目前最大出现次数 cnt,如果是,说明该元素成为新的众数,我们更新 majority 为当前元素,cnt 更新为该元素的出现次数。最后,遍历结束后,majority 变量中保存的就是数组中出现次数最多的元素。通过这种方式,我们能够高效地找出众数,且时间复杂度为 O(n),空间复杂度为 O(n)。

哈希表法代码:

class Solution {
public:int majorityElement(vector<int>& nums) {// 使用哈希表记录每个数字的出现次数unordered_map<int, int> counts;// 初始化 majority 为 0, 用于保存当前候选的众数// 初始化 cnt 为 0, 用于记录当前众数的出现次数int majority = 0, cnt = 0;// 遍历数组 nums 中的每个元素for (int num: nums) {// 更新哈希表中当前数字的出现次数++counts[num];    // 如果当前数字的出现次数大于当前最大出现次数 cntif (counts[num] > cnt) {// 更新众数为当前数字majority = num;// 更新当前众数的出现次数为该数字的出现次数cnt = counts[num];}}// 返回数组中出现次数最多的数字(众数)return majority;}
};

排序法

我们首先对数组 nums 进行排序。排序之后,数组中的元素按从小到大的顺序排列,众数必定出现在数组的中间位置。因为根据题意,众数的出现次数超过了数组长度的一半,因此它必定会在排序后的数组的中间位置。具体来说,我们通过访问 nums[nums.size() / 2] 来直接获取这个中间元素,即为数组中的众数。通过这种方式,我们能够在 O(n log n) 的时间复杂度下,快速地找到众数。

排序法代码:

class Solution {
public:int majorityElement(vector<int>& nums) {sort(nums.begin(), nums.end());  //对数组进行排序//由于众数的出现次数超过数组长度的一半,排序后它必定位于中间位置return nums[nums.size() / 2];//返回排序后的数组中间位置的元素}
};

三种方法对比

方法核心原理时间复杂度空间复杂度优点缺点
摩尔投票法元素抵消策略O(n)O(1)效率最高,空间最优需保证多数元素存在
哈希表法哈希计数O(n)O(n)直观易理解,适用性广空间占用高
排序法中位数即众数
(因 count>⌊n/2⌋)
O(nlog⁡n)O(1)或 O(n)代码最简洁修改原数组,效率最低
http://www.dtcms.com/a/512683.html

相关文章:

  • 清远专业网站建设服务阿里云个人网站制作
  • 河北省保定市唐县城乡建设网站wordpress仿异次元下载页
  • springboot优雅停止的流程梳理
  • 音视频开发远端未发布视频占位图
  • 贵阳网站开发推荐你的网站赚钱吗
  • 上海备案证查询网站查询网站查询系统桂林论坛网站建设
  • QT6中三种设置控件及窗口大小的函数
  • 现在的网站前端用什么做综合返利商城网站建设
  • 河南省建设厅网网站首页没备案的网站收录
  • 织梦网站标题被改学校招生网络营销方案
  • 从0到1:如何用统计学“看透”不同睡眠PSG数据集的差异(域偏差分析实战)
  • 如何做淘宝优惠卷网站网站业务员怎么给客户做方案
  • 网站空间后台登录长沙seo服务
  • 灵敏度、稳定性、便携性三重突破——小吉BL-08plus为何成禽病防控新标配?
  • ubuntu 中使用 lftp 命令行工具传输文件
  • 推荐5款中文打字速度测试软件:无需下载即可使用
  • 网站建设基础服务wordpress polling
  • 长春 网站 设计公司wordpress 权限
  • 什么在线做动图的网站比较好织梦调用wordpress
  • 用 Python 给 Amazon 做“全身 CT”——可量产、可扩展的商品详情爬虫实战
  • 开箱即用,15分钟极速部署:富唯智能精密仪器搬运机器人重塑工业自动化
  • 网站建设个人实训报告seo免费入门教程
  • 一个服务器下怎么做两个网站吗网站上海备案查询系统
  • STM32实现呼吸灯效果原理
  • 做营销网站要多少钱网站开发平台建设
  • html css js网页制作成品——HTML+CSS仙台有树电视剧网页设计(5页)附源码
  • 开发避坑指南(64):修复IllegalArgumentException:参数值类型与期望类型不匹配
  • 企业网站怎样做seo优化 应该如何做凡科建站官网怎么样
  • 【Java进阶】GC友好的编程方式
  • 甘肃肃第八建设集团网站福州市高速公路建设指挥部网站