【LeetCode】剑指 Offer 39. 数组中出现次数超过一半的数字 p205 -- Java Version
题目链接:https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/
1. 题目介绍(39. 数组中出现次数超过一半的数字)
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
【测试用例】:
示例1:
输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2
【条件约束】:
提示:
- 1 <= 数组长度 <= 50000
【相关题目】:
注意:本题与主站 169. 多数元素 题目相同。
2. 题解
2.1 暴力穷举 – O(n2)
时间复杂度O(n2),空间复杂度O(n)
【解题思路】:
对于排序数组,我们可以很容易统计出每个数字出现的次数,可参考 剑指 Offer 53 - I. 在排序数组中查找数字 I ,然后再对次数进行判断,看是哪个数字出现的次数超过了数组长度的一半。
……
【实现策略】:
- 对输入数组 nums 使用
sort()方法进行升序排序;
【sort()方法详解】:详述Java中sort排序函数- 定义一个
HashMap用来记录每个数字在数组中出现的次数,数组中数组为键,出现的次数为值;
【注意点】:HashMap 的键虽然不能重复,但是如果是有重复键的键值对要加入,那么 新值会覆盖掉旧值,切记!- 双循环穷举,当然下面为了提高效率,同时防止重复键值对被覆盖,通过每次循环中把
j赋值给i的操作,这样就保证了内循环结束后,i位于当前重复数字的末尾,而由于循环结束,i++的原因,这样就相当于间接的移动i到了下一个非重复数组数字的位置,然后进行下一个数字重复次数的统计;(这里的双循环穷举,可以改为 一次遍历 + 二分查找(找左右边界) 的方式,进一步提高统计效率)- 最后,遍历
HashMap,找出次数超过数组一半的数字并返回。
class Solution {public int majorityElement(int[] nums) {// 对数组进行排序Arrays.sort(nums);// 遍历数组// 定义map用来记录每个数字在数组中出现的次数HashMap<Integer,Integer> map = new HashMap<>();int n = 0;for(int i = 0; i < nums.length; i++){for (int j = i; j < nums.length; j++){if (nums[j] == nums[i]) {n++;i = j; // 将i移到下一个数的位置} }map.put(nums[i],n);n = 0;}// 遍历map,找出超过一半数组长度的数字for(Map.Entry<Integer,Integer> entry : map.entrySet()){if (entry.getValue() > nums.length/2) return entry.getKey();}return 0;}
}

代码简化:
【实现策略】:
看了题解,意识到自己傻冒了,忘了 HashMap 中有containsKey()方法了,那么完全可以直接一次遍历数组nums,用HashMap统计各数字的数量,即可找出众数,根本不用双循环,一个一个对比,直接单次循环,containsKey(下一个数字),有就++,没有就移动到下一个就完了,此方法时间和空间复杂度均为 O(n) 。
- 一次遍历,在遍历的过程中将数组数字存入 HashMap ;
- 判断 HashMap 的键是否已有当前数字,有就加1,没有就下一个。
……
但是不知道为啥,这样好慢,比没简化的代码要慢的多,估计应该是力扣的测试用例设置的不太好。
class Solution {public int majorityElement(int[] nums) {// 遍历数组// 定义map用来记录每个数字在数组中出现的次数HashMap<Integer,Integer> map = new HashMap<>();for(int i = 0; i < nums.length; i++){if (!map.containsKey(nums[i])) map.put(nums[i],1);else map.put(nums[i], map.get(nums[i])+1);}// 遍历map,找出超过一半数组长度的数字for(Map.Entry<Integer,Integer> entry : map.entrySet()){if (entry.getValue() > nums.length/2) return entry.getKey();}return 0;}
}

2.2 数组排序法 – O(nlogn)
时间复杂度O(nlogn),空间复杂度O(1)
【解题思路】:
将数组nums排序,数组中点的元素 一定为众数。
根据题目所出的数组特性:数组中有一个数字出现的次数超过了数组长度的一半,那么如果对这个数组进行排序,排序之后位于数组中间的数字一定就是那个出现次数超过数组长度一半的数字。
……
【实现策略】:
根据上面的思路,代码就变的异常的轻松加愉快:
- 排序
- 返回数组的中点数字
……
当然如果返回值一变,要求返回该数字的重复次数,这个方法就趴菜了,不过题目摇身一变就变成了剑指 Offer 53 - I. 在排序数组中查找数字 I ,可用 2.1 中的方法解决。
class Solution {public int majorityElement(int[] nums) {// 对数组进行排序Arrays.sort(nums);// 遍历数组return nums[nums.length/2];}
}

2.3 摩尔投票法(原书题解2) – O(n)
时间复杂度O(n),空间复杂度O(1)
【解题思路】:
核心理念为 票数正负抵消,因为题目中明确的指出了,要返回的数字是在数组中出现次数超过一半的数字,那么通过正负抵消,最后能留下的一定是该数字。
推论一: 若记 众数 的票数为 +1,非众数 的票数为 -1,则一定有所有数字的 票数和 >0 ;
推论二: 若数组的前 a 个数字的 票数和 =0 ,则 数组剩余 (n−a) 个数字的 票数和一定仍 >0 ,即后 (n−a) 个数字的 众数仍为 x 。
……
【实现策略】:
- 定义
x存储众数(候选人),定义票数votes;- 一次遍历,判断当前票是否是给当前候选人的,如果是则加1,如果不是则减1,当候选人的票数为0时,则更换新的候选人。
……
【唠叨两句】:
原书题解1 采用了快排思想的排序方法Partition(),一直到 Partition() 方法随机到中点,即,将比中点数小的数字移到数组的左边,比中点数大的数组移到数组的右边。此方法可以,但没必要,除非题目要求不能使用库函数,不然感觉倒是没必要自己写排序,
class Solution {public int majorityElement(int[] nums) {int x = 0, votes = 0, count = 0;for(int num : nums){if(votes == 0) x = num;votes += num == x ? 1 : -1;}// 验证 x 是否为众数for(int num : nums)if(num == x) count++;return count > nums.length / 2 ? x : 0; // 当无众数时返回 0}
}

3. 参考资料
[1] 剑指 Offer 39. 数组中出现次数超过一半的数字(摩尔投票法,清晰图解)
[2] Java遍历Map的几种方法
[3] 【Java】 剑指offer(53-1) 数字在排序数组中出现的次数
相关文章:
【LeetCode】剑指 Offer 39. 数组中出现次数超过一半的数字 p205 -- Java Version
题目链接:https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/ 1. 题目介绍(39. 数组中出现次数超过一半的数字) 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 你可…...
fisco bcos用caliper0.2.0进行压力测试的安装配置
一、前期环境 1. 硬件 需要外网权限 2. 操作系统 版本要求:Ubuntu > 16.04, CentOS > 7, MacOS > 10.14 3. 基础软件 python 2.7,make,g,gcc,git sudo apt install python2.7 make g gcc git curl git confi…...
正在进行 | 用友企业数智化财务峰会落地广州 高能不断
3月28日,以「智能会计 价值财务」为主题的“2023企业数智化财务创新峰会”登陆广州。 此次用友企业数智化财务创新峰会,邀请了知名院校的专家学者、央国企等大型企业财务数智化领路人以及羊城权威媒体,近千人相约广州越秀国际会议中心,深度聚焦大型企业财务数智化创新应用…...
uniapp - APP云打包、蒲公英平台发布APP的步骤
一、uniapp 云打包 1、注册 dcloud 开发者 首先需要注册一个 dcloud 开发者的账号 dcloud开发者中心:登录 (dcloud.net.cn) 根据流程注册即可。 2、云打包(已安卓为例) 项目创建完成后,查看 dcloud 开发者中心,看是否…...
reposync命令详解--reposync同步aliyunyum库到本地
参考: reposync - 命令 - -桃枝夭夭- - 博客园 0. 简介 reposync 命令简单来说就是可以把指定外网源(repo id)的包同步到本地文件中 1. 安装 reposync 命令 [rootV10SP1-1 ~]# yum install -y dnf-plugins-core2. 常用选项以及参数 选项含义-c [fil…...
OCR之论文笔记TrOCR
文章目录TrOCR: Transformer-based Optical Character Recognition with Pre-trained Models一. 简介二. TrOCR2.1. Encoder2.2 Decoder2.3 Model Initialiaztion2.4 Task Pipeline2.5 Pre-training2.6 Fine-tuning2.7 Data Augmentation三. 实验3.1 Data3.2 Settings3.2 Resul…...
雷电4模拟器安装xposed框架(2022年)
别问我都2202年了为什么还在用雷电4安卓7。我特么哪知道Xposed的相关资料这么难找啊,只能搜到一些老旧的资料,尝试在老旧的平台上实现了。 最初的Xposed框架现在已经停止更新了,只支持到安卓8。如果要在更高版本的安卓系统上使用Xposed得看看…...
微信小程序支付完整流程(前端)
微信小程序中,常见付款给商家的场景,下面列出企业小程序中,从0起步完整微信支付流程。 一,注册微信支付商户号(由上级或法人注册) 接入微信支付 - 微信商户平台 此商户号,需要由主管及更上级领导…...
设置鼠标右键打开方式,添加IDEA的打开方式
一、问题描述 已下载IDEA,但是右键打开之前保存的项目文件,无法显示以IDEA方式打开。 二、解决步骤 1. 打开注册表 winR键输入regedit 2、查找路径为计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Directory\shell (我找了半天没看到Class…...
LAMP架构之zabbix监控(2):zabbix基础操作
目录 一、zabbix监控节点添加和删除 (1)手动添加 (2)自动添加 (3)按照条件批量添加 (4)使用api工具进行管理 二、针对应用的zabbix监控 一、zabbix监控节点添加和删除 实验说明&a…...
ShareSDK常见问题
QQ-分享报错901111,9001010等 由于QQ现在需要审核后才可以分享(之前分享不需要审核),所以此错误解决方法只需通过腾讯开放平台的审核即可,另外要检查注册好的应用的基本信息,包名、md5签名和Bundle id是不…...
[Spring]一文明白IOC容器和思想
✅作者简介:大家好,我是Philosophy7?让我们一起共同进步吧!🏆 📃个人主页:Philosophy7的csdn博客 🔥系列专栏: 数据结构与算法 👑哲学语录: 承认自己的无知,乃…...
程序人生 | 与足球共舞的火柴人(致敬格拉利什,赋予足球更深的意义)
个人简介 👀个人主页: 前端杂货铺 🙋♂️学习方向: 主攻前端方向,也会涉及到服务端 📃个人状态: 在校大学生一枚,已拿多个前端 offer(秋招) 🚀未…...
MATLAB | R2023a更新了哪些好玩的东西
R2023a来啦!!废话不多说看看新版本有啥有趣的玩意和好玩的特性叭!!把绘图放最前面叭,有图的内容看的人多。。 1 区域填充 可以使用xregion及yregion进行区域填充啦!! x -10:0.25:10; y x.^…...
Python Module — OpenAI ChatGPT API
目录 文章目录目录OpenAI Python SDKopenai.ChatCompletion 模块openai.ChatCompletion.create 函数OpenAI Python SDK 官方文档:https://platform.openai.com/docs/api-reference/introduction OpenAI Python SDK 用于开发与 OpenAI RESTful API 进行交互的客户端…...
Docker学习记录
阅读前请看一下:我是一个热衷于记录的人,每次写博客会反复研读,尽量不断提升博客质量。文章设置为仅粉丝可见,是因为写博客确实花了不少精力。希望互相进步谢谢!! 文章目录阅读前请看一下:我是一…...
Linux-VIM使用
文章目录前言VIM使用1、切换模式2、跳转(1) 跳转到指定行(2) 跳转到首行(3) 跳转到末行3、自动格式化程序4. 大括号对应5. 删除(1)删除一个单词(2)删除光标位置至行尾(3)删除光标位置至行首(4&a…...
Windows安全中心内存完整性无法打开问题的处理方法
Windows11安全中心内存完整性无法打开 今天电脑使用过程中突然看到系统桌面右下角任务栏中 windows安全中心图标出现了警告信息,如下图红框所示: 点击该图标进入windows安全中心的 安全性概览 界面,如下图: 在该界面可以看到出现安…...
在芯片设计行业,从项目的初期到交付,不同的岗位的工程师主要负责什么?
大家都知道在芯片设计行业,项目是至关重要的一环。从项目的初期到交付,不同的岗位的工程师在项目的各环节主要负责什么?他们是怎样配合的?下面看看资深工程师怎么说。 一个项目,从初期到交付的过程是比较漫长的。我们知道最早的时候&#…...
Spring Cloud Alibaba全家桶(七)——Sentinel控制台规则配置
前言 本文小新为大家带来 Sentinel控制台规则配置 相关知识,具体内容包括流控规则(包括:QPS流控规则,并发线程数流控规则),BlockException统一异常处理,流控模式(包括:直…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
深入剖析AI大模型:大模型时代的 Prompt 工程全解析
今天聊的内容,我认为是AI开发里面非常重要的内容。它在AI开发里无处不在,当你对 AI 助手说 "用李白的风格写一首关于人工智能的诗",或者让翻译模型 "将这段合同翻译成商务日语" 时,输入的这句话就是 Prompt。…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...
Mysql8 忘记密码重置,以及问题解决
1.使用免密登录 找到配置MySQL文件,我的文件路径是/etc/mysql/my.cnf,有的人的是/etc/mysql/mysql.cnf 在里最后加入 skip-grant-tables重启MySQL服务 service mysql restartShutting down MySQL… SUCCESS! Starting MySQL… SUCCESS! 重启成功 2.登…...
PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...
0x-3-Oracle 23 ai-sqlcl 25.1 集成安装-配置和优化
是不是受够了安装了oracle database之后sqlplus的简陋,无法删除无法上下翻页的苦恼。 可以安装readline和rlwrap插件的话,配置.bahs_profile后也能解决上下翻页这些,但是很多生产环境无法安装rpm包。 oracle提供了sqlcl免费许可,…...
【UE5 C++】通过文件对话框获取选择文件的路径
目录 效果 步骤 源码 效果 步骤 1. 在“xxx.Build.cs”中添加需要使用的模块 ,这里主要使用“DesktopPlatform”模块 2. 添加后闭UE编辑器,右键点击 .uproject 文件,选择 "Generate Visual Studio project files",重…...

