力扣面试经典算法150题:多数元素

多数元素

今天的题目是力扣面试经典150题中的数组的简单题: 多数元素

题目链接:https://leetcode.cn/problems/majority-element/description/?envType=study-plan-v2&envId=top-interview-150

题目描述

给定一个大小为 n 的数组 nums,其中包含 n 个整数,假设有一个元素出现的次数超过 ⌊ n/2 ⌋ 次,则称之为多数元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
请编写一个程序来找出这个多数元素。

  • 注意:
    • 数组 nums 的长度为 n。
    • 数组中的多数元素出现的次数超过 ⌊ n/2 ⌋ 次。
    • 不需要考虑超出新长度以外的元素。
  • 示例:
    • 输入:
      nums = [3,2,3]
    • 输出:
      多数元素为 3
    • 解释:
      数组 nums 中的值 3 出现了两次,超过了一半的次数。
      因此,多数元素为 3。

题目分析

  1. 确定目标需求:找出多数元素,即出现次数超过数组长度一半的元素。

  2. 提取题目信息:给定一个大小为n的数组nums,也就是说我们已知的条件有两个,一个是数组大小n,这个字段我们用于判断元素是否为多数元素,另外就是数组nums,作为元素来源。

  3. 你可以假设数组是非空的,并且给定的数组总是存在多数元素。这段话提示我们,给定的数组必定会存在多数元素。

  4. 没有要求不能使用额外空间。

解题思路

没有要求不使用额外空间,那么最容易想到的就是使用map存储元素以及出现次数。

在循环数组时,我们可以同时校验出现次数,因为多数元素是定义超过一半的出现次数,因此这个元素有且只有一个,出现一个即可直接结束循环。

实际算法代码

根据以上分析和思路,我们可以写出以下代码:

public class MajorityElement {public static void main(String[] args) {MajorityElement solution = new MajorityElement();// 示例数据int[] nums = {3, 2, 3};// 调用查找多数元素方法int majorityElement = solution.majorityElementByHash(nums);// 输出多数元素System.out.println("Majority element: " + majorityElement);}/*** 查找多数元素** @param nums 输入数组* @return 多数元素*/public int majorityElementByHash(int[] nums) {// 定义符合条件的目标次数int targetCount = nums.length / 2;// 定义目标变量Integer candidate = null;// 定义存储出现次数的mapMap<Integer, Integer> map = new HashMap<>();for (int num : nums) {// 当前元素出现的次数,未出现过为0Integer count = map.getOrDefault(num, 0);// 本次出现,count是历史出现次数count++;// 当前出现次数大于目标次数,是多数元素,赋值后结束循环if (count > targetCount) {candidate = num;break;}else {// 不大于目标次数,说明没满足多数元素定义,记录出现次数,继续循环map.put(num, count);}}return candidate;}}

执行后满足题目要求:

在这里插入图片描述

提交到力扣也正常 通过测试:

在这里插入图片描述

但是事情并没有这么简单。

排序法

题目中说到给定的数组必定有多数元素,而多数元素是出现次数超过数组长度一半的元素。那么假如我给数组排个序,这个元素是不是一定出现在数组中间的位置?

于是有了以下代码:

	--snip--/*** 查找多数元素** @param nums 输入数组* @return 多数元素*/public int majorityElementBySort(int[] nums) {// 对数组进行排序Arrays.sort(nums);// 计算数组的中位数索引int midIndex = nums.length / 2;// 返回中位数元素return nums[midIndex];}--snip--

启动程序,测试也通过了。

在这里插入图片描述

提交到力扣看看:

在这里插入图片描述

依旧没有问题!

但是事情还是没有这么简单。

摩尔投票法

‌摩尔投票法(Moore’s Voting Algorithm)是一种用于在数组或序列中查找出现次数超过一半的主要元素的算法。这种算法的核心思想是通过不同元素之间的抵消来找到可能的主要元素候选者,并在最后验证候选者是否真正满足要求。摩尔投票法的主要应用场景是寻找数组中的多数元素,即出现次数超过数组长度一半的元素。

算法原理

摩尔投票法的基本思想是通过遍历数组,对每个元素进行投票。当遇到相同的元素时,增加票数;当遇到不同的元素时,减少票数。最终,票数最多的元素即为多数元素。这种算法的关键在于利用不同元素之间的抵消,使得最终剩下的元素成为出现次数最多的候选者。

使用摩尔投票法实现代码如下:

/*** 查找多数元素** @param nums 输入数组* @return 多数元素*/public int majorityElement(int[] nums) {int count = 0;Integer candidate = null;// 摩尔投票算法for (int num : nums) {if (count == 0) {candidate = num;}count += (num == candidate) ? 1 : -1;if (count > ( nums.length / 2)) break;}return candidate;}

比较

使用hash的方式属于暴力解题,效率是最低的。排序法和摩尔投票法相对要好一点,所以比较一下:

排序法

  • 优点:
    • 简单直观:排序法的实现逻辑简单,易于理解和实现。
    • 适用性广:适用于任何类型的数组,无论数组是否有序。
    • 确定性:在排序后,多数元素的位置是确定的,位于数组的中间位置。
  • 缺点:
    • 时间复杂度较高:排序的时间复杂度通常为 O(n log n),其中 n 是数组长度。
    • 可能的空间开销:虽然大多数现代排序算法都是原地排序,但有些排序算法(如归并排序)需要 O(n) 的额外空间。
    • 不适合大数据集:对于非常大的数据集,排序可能会变得非常慢。

摩尔投票法

  • 优点:
    • 线性时间复杂度:摩尔投票法的时间复杂度为 O(n),其中 n 是数组长度。
    • 常数空间复杂度:只需要 O(1) 的额外空间。
    • 高效:特别适合处理大数据集或实时流数据的情况。
    • 无需排序:不需要对数组进行排序,避免了排序带来的额外时间开销。
  • 缺点:
    • 理解难度:相对于排序法,摩尔投票法的实现逻辑较为复杂,理解起来可能需要一些时间。
    • 适用范围有限:仅适用于存在多数元素的情况,即数组中确实存在一个元素出现次数超过 n/2 的情况。

方法总结

排序法 更适合小规模数据集或对实现简单性和可读性有较高要求的应用场景。
摩尔投票法 更适合大规模数据集或对时间和空间效率有较高要求的应用场景。

选择建议

如果数组长度较小,或者对代码的可读性和实现的简单性有较高要求,可以选择 排序法。
如果数组长度较大,或者对算法的时间复杂度和空间复杂度有严格限制,推荐使用 摩尔投票法。

总结

官方的方法有五种,这里不一一介绍。

第一种是比较容易想出来的,也是我第一时间使用的解法。

第二种也不难,差的可能是灵光一闪。

第三种可能就有有一点数学思想归纳总结。

大家也可以学习一下官方的两外两种办法分治和随机化。

加油!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/395454.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法 二

求中点 LR&#xff0c;可能溢出 除以2&#xff0c;等同于右移一位 递归、递归的时间复杂度 母问题的规模 子问题的规模&#xff0c;且都相等 调用次数 不用展开看&#xff0c;就看一层。 归并排序 时间复杂度降低的原因&#xff1a;没有浪费比较。比如选择排序&#xff…

财务会计与管理会计(一)

文章目录 销售业绩统计图表OFFSET函数在制作图表数据中的应用 自动计算分项合计1、IF函数2、SUM函数3、SUMPRODUCT函数 自动打印快递邮寄单OFFSET函数在逐行获取数据中的应用 销售业绩统计图表 OFFSET函数在制作图表数据中的应用 B150FFSET($A$2,$M$1,COLUMN(B1)-1) B150FFSE…

Netty技术全解析:LineBasedFrameDecoder类深度解析

❃博主首页 &#xff1a; 「码到三十五」 &#xff0c;同名公众号 :「码到三十五」&#xff0c;wx号 : 「liwu0213」 ☠博主专栏 &#xff1a; <mysql高手> <elasticsearch高手> <源码解读> <java核心> <面试攻关> ♝博主的话 &#xff1a…

NSSCTF练习记录:[SWPUCTF 2021 新生赛]include

题目&#xff1a; 随便传入一个file 因为存在include_once函数&#xff0c;可以使用php伪协议获取flag.php源码&#xff0c;再通过base64解码得到flag。 php:// 访问各个输入/输出流&#xff0c;常用php://filter和php://input&#xff0c;php://filter用于读取源码&#xff…

LLC数字控制TMS320F28034,4-DSP的epwm配置介绍

LLC数字控制TMS320F28034&#xff0c;4-DSP的epwm配置介绍 1 TMS320F280341.1 概述1.2 PWM详细介绍 2 TMS320F28034 PWM功能框图2.1 ePWM功能模块2.2 ePWM功能寄存器框图 3 TMS320F28034 PWM初始化流程4 结合项目设计5 代码设计5.1 PWM初始化程序5.2 工程代码 6 总结 配套代码示…

Linux/C 高级——shell脚本

1. shell脚本基础概念 1.1概念 shell使用方式&#xff1a;手动下命令和脚本 脚本本质是一个文件&#xff0c;文件里面存放的是特定格式的指令&#xff0c;系统可以使用脚本解析器翻译或解析指令并执行&#xff08;它不需要编译&#xff09;。 shell脚本本质&#xff1a;shell命…

中国信息学奥赛专用系统之----NOI Linux 2.0系统安装教程

1、下载NOI Linux 2.0系统&#xff0c;下载地址&#xff1a; https://noiresources.ccf.org.cn/ubuntu-noi-v2.0.iso 2、新建虚拟机 3、开机安装系统 下载插件&#xff0c;可能需要10分钟以上。 5、进系统看看 OK,NOI Linux 2.0系统安装完毕&#xff01;

【学习笔记】用线段树维护区间计数问题

前言 简单的区间计数问题可能直接推式子就行了。 但有些问题必须要数据结构维护。线段树就是一个比较好的处理区间的数据结构。 Gym102222L 思路 满足条件的区间特征&#xff1a; max ⁡ { a i } − min ⁡ { a i } 1 − c n t 0 \max\{a_i\}-\min\{a_i\}1-cnt0 max{ai​}…

解锁创意之门:如何使用DALL·E-3创作惊艳的图像

在这个视觉驱动的时代&#xff0c;图像已经成为表达创意和传递信息的重要媒介。最近&#xff0c;OpenAI发布了新一代的图像生成模型——DALLE-3&#xff0c;它以其卓越的生成能力和细致的图像质量迅速成为了创意工作者的热门工具。今天&#xff0c;我将带你一步步了解如何使用D…

13.3 正则表达式的应用

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

2024年6月scratch图形化编程等级考试三级真题

202406 青少年软件编程等级考试Scratch三级真题 试卷总分数&#xff1a;100分 考试时长&#xff1a;60 分钟 第 1 题 运行程序后&#xff0c;角色的x坐标是&#xff1f;&#xff08; &#xff09; A&#xff1a;99 B&#xff1a;100 C&#xff1a;199 D&#xff1a;200 正…

矩阵的导数运算

1. 标量方程对向量的导数 一维方程f(y)求极值即求导,令 二维方程f(y1,y2)求极值即求偏导,令 如果一个标量方程f(y1,y2,...ym)有m个自变量,求取它的极值就需要求取m组的方程组。当然可以用一种简洁的方式来表达它,比如二维方程f(y1,y2)可以把其中的变量写成向量的形式,此…

指针基础知识(笔记)

文章目录 1. 概念理解2. 空指针和野指针3. 计算4. 小结5. size_t6. 案例一: 指针查找并返回指定元素索引7. 指针访问多维数组(涉及 int (*ptr)[3]解析)8. 指针数组9. 函数的值传递与地址引用传递① 函数的值传递(pass by value)② 地址传递(pass by reference) 10. 案例二&…

C语言宠物系统

功能有增加宠物信息&#xff0c;显示宠物信息&#xff0c;删除宠物信息&#xff0c;修改功能和排序功能&#xff0c;可以选择姓名排序&#xff0c;年龄排序&#xff0c;价格排序。进阶的功能有文件操作&#xff0c;动态内存开辟。。 test.c源文件 #include "Pet.h"v…

机器人帮助文档

文章目录 机器交流使用群使用图例1. 查看机器人使用文档2. 直接问问题&#xff08;系统默认AI&#xff09;3. 系统默认AI切换4. 直接问问题&#xff08;指定讯飞星火AI&#xff09;5. 直接问问题&#xff08;指定百度文心AI&#xff09;6. 直接问问题&#xff08;指定谷歌AI&am…

代码随想录算法训练营Day34 | 62.不同路径 | 63. 不同路径 II | 343.整数拆分 | 96.不同的二叉搜索树

今日任务 62.不同路径 题目链接&#xff1a; https://leetcode.cn/problems/unique-paths/description/题目描述&#xff1a; Code class Solution { public:int uniquePaths(int m, int n) {// vector<vector<int>> memo(m, vector<int>(n, -1));// fu…

从0开始的1panel搭配雷池社区版保护网站

1.安装1panel 使用默认安装地址&#xff1a;/opt [1Panel Log]: 外网地址: http://xxxxx:35628/dc54fe6a54 [1Panel Log]: 内网地址: http://10.0.4.3:35628/dc54fe6a54 [1Panel Log]: 面板用户: root [1Panel Log]: 面板密码: xxxxx 安装完成第一次登陆 安装openresty&…

【原创】springboot+mysql法律咨询网设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

初学51单片机1602液晶时序图实例分析

上篇博文笔者分享了关于液晶1602基本的工作流程&#xff0c;本篇主要是通过逻辑分析仪来看一下程序使能的电平时序&#xff0c;是否符合产品文档给出 的时序逻辑。 先看一下1602的时序图 认识下时序图中各个标识的含义&#xff1a; Tc信号周期&#xff08;E Cycle Time&#x…

【解压既玩】PS3模拟器v0.0.32+战神3+战神升天+各存档 整合包 ,完美不死机,没有BUG,旷世神作,强力推荐

战神3是圣莫尼卡公司的大作&#xff0c;PS3 上必玩的游戏之一。 本文收集了战神3和升天两作&#xff0c;附存档&#xff0c;完美不死机&#xff0c;没有BUG&#xff0c;强烈推荐。 解压即玩。 立即下载&#xff1a;【chumenx.com】【解压既玩】PS3模拟器v0.0.32战神3战神升天…