数组中出现次数超过一半的数字(简单难度)

简介: 数组中出现次数超过一半的数字(简单难度)

题目概述(简单难度)

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

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

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]
输出: 2

附上leetcode链接:

点击此处进入链接


思路与代码

思路展现

思路1(排序法)

排序法的思想其实非常简单,一个数组中出现次数最多的数字经过排序后,这个数组最中间的数字一定是这个出现次数最多的数字.

其实很容易证明,假设排序之后数组的中间值不是最多的元素,那么这个最多的元素要么是在数组前半部分,要么是在数组的后半部分,无论在哪,他的长度都不可能超过数组长度的一半。


代码示例

  public int majorityElement(int[] nums) {
        Arrays.sort(nums);
        return nums[nums.length / 2];
    }

时间复杂度:O(nlogn)。将数组排序的时间复杂度为 O(nlogn)。


空间复杂度:O(logn)。如果使用语言自带的排序算法,需要使用 O(logn) 的栈空间。如果自己编写堆排序,则只需要使用 O(1)的额外空间。


思路2(摩尔投票法,最优解)

也是这道题目最经典的解法:使用摩尔投票法,摩尔投票法的思路是这样的:


假如我们有个职位,需要从 A,B 两位候选人中选出
先抽出一张票,投的是 A,我们在黑板上写着当前胜利者:A,票数:1
再抽出一张票,投的是 A,我们在黑板上写着当前胜利者:A,票数:2
再抽出一张票,投的是 B,用一张 B 抵消一张 A 的选票,我们在黑板上写着当前胜利者:A,票数:1
再抽出一张票,投的是 B,用一张 B 抵消一张 A 的选票,我们在黑板上写着当前胜利者:无,票数:0
再抽出一张票,投的是 A,我们在黑板上写着当前胜利者:A,票数:1
抽取完毕,恭喜 A 获胜,赢得该职位。

经过以上实例分析,我们可以得出 3个要点:


1:不同候选人的选票之间,可以一一抵消。

2:若当前胜利者存在多张选票时,不同的候选人的票,只能抵消一张当前胜利者的票。

3:若当前双方的选票被抵消为零,下一次抽出的候选人,将作为暂时的胜利者领先。


下面给出一位大佬的动画演示地址:非常清晰明了:

戳我戳我


代码示例

class Solution {
    public int majorityElement(int[] nums) {
        int major = nums[0];
        int count = 1;
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) {
                //前面都消完了,在重新赋值
                count++;
                major = nums[i];
            } else if (major == nums[i]) {
                //自己人,count就加1
                count++;
            } else {
                //不是自己人就同归于尽,消掉一个
                count--;
            }
        }
        return major;
    }
}

时间复杂度:O(n) 摩尔投票法只对数组进行了一次遍历。


空间复杂度:O(1) 摩尔投票法只需要常数级别的额外空间。


总结

这道题目的常规算法有很多,举例如下:

1:哈希表(常用)

2:排序(常用)

3:位运算

4:摩尔投票法(最优解)

最经典的摩尔投票法希望大家能好好学习下,后续会将哈希的解法进行更新.


相关文章
|
前端开发 JavaScript 测试技术
CSS3 动画效果对网站性能有什么影响?
CSS3动画效果在为网站带来丰富视觉体验的同时,也会对网站性能产生多方面的影响
573 58
|
3月前
|
缓存 数据安全/隐私保护 芯片
中控网 item_search - 根据关键词获取公司列表接口对接全攻略:从入门到精通
中控网item_search接口支持通过关键词批量检索企业信息,涵盖行业、地域、资质等维度,适用于供应商挖掘、市场调研等场景。本攻略详解接口调用、签名生成、分页获取及优化策略,助力开发者高效对接,快速实现精准企业数据采集与应用。
|
人工智能 供应链 安全
暸望塔丨三大投入,为中国企业走向全球铺路搭桥
面对新一轮的历史机遇,阿里云将以战略级的投入,为中国企业出海提供一流的基础设施、一流的技术和一流的服务,与最优秀的中国企业在全球并肩前行,共赴新的大航海时代。
暸望塔丨三大投入,为中国企业走向全球铺路搭桥
|
1月前
|
存储 人工智能 前端开发
从 DDD 到 Workflow Runtime:拆解 Coze Studio 的全栈技术架构
从 AI Agent 平台定位、DDD 分层与 crossdomain 设计出发,重点剖析 Coze Studio 基于 Eino 的智能体与工作流运行机制、事件驱动的资源与搜索体系及会话关键路径,并简要展望多模型协同和基础设施可插拔的演进方向。
266 0
|
7月前
|
缓存 Java
自旋锁
自旋锁是一种轻量级同步机制,适用于多线程环境。其核心思想是线程在获取锁失败时不阻塞,而是通过忙等待(自旋)不断尝试获取锁,从而避免上下文切换的开销。常见实现依赖CAS原子操作,适用于锁持有时间短、并发度高的场景,如计数器更新或缓存操作。但长时间自旋会浪费CPU资源,因此更适合多核环境下使用。Java中可通过`AtomicBoolean`实现简单自旋锁,JVM也对其进行了自适应优化。合理使用可提升性能,但需注意控制自旋时间和竞争粒度。
298 0
|
运维 安全 Linux
龙蜥衍生版KerarchOS迁移方案及实践分享|龙蜥大讲堂106期
本次分享来自龙蜥大讲堂106期,主题为“龙蜥衍生版KerarchOS迁移方案及实践”。内容涵盖服务器操作系统现状、安全高性能操作系统KeyarchOS的介绍、CentOS停服后的应对策略(重装或迁移),以及CentOS停更带来的危机与迁移背景。重点介绍了两种迁移方案:原地迁移和扩展迁移,并详细讲解了KeyarchOS迁移工具X2Keyarch的操作流程。通过实际案例展示了操作系统迁移的具体步骤和效果,帮助用户更好地理解和实施迁移工作。
243 7
|
6月前
|
运维 测试技术 Docker
Docker:轻量级容器化技术革命
Docker:轻量级容器化技术革命
|
数据采集 搜索推荐 数据管理
数据架构 CDP 是什么?
数据架构 CDP 是什么?
749 2
|
9月前
|
关系型数据库 MySQL 程序员
菜鸟之路day31一一MySQL之多表设计
本文由blue撰写于2025年5月9日,主要介绍了MySQL多表设计的三种关系:一对多、一对一和多对多。一对多通过在“多”的一方添加关联字段实现,如部门与员工的关系;一对一通常用于单表拆分,通过唯一外键关联,例如学生与学生证的关系;多对多则需创建中间表,包含两个外键分别关联两方主键,如学生与课程的关系。文中还提供了实际案例,包括分类表、菜品表、套餐表及它们之间的关联设计,详细展示了多表设计的应用场景与实现方法。
349 14
|
11月前
|
存储 算法 文件存储
探秘文件共享服务之哈希表助力 Python 算法实现
在数字化时代,文件共享服务不可或缺。哈希表(散列表)通过键值对存储数据,利用哈希函数将键映射到特定位置,极大提升文件上传、下载和搜索效率。例如,在大型文件共享平台中,文件名等信息作为键,物理地址作为值存入哈希表,用户检索时快速定位文件,减少遍历时间。此外,哈希表还用于文件一致性校验,确保传输文件未被篡改。以Python代码示例展示基于哈希表的文件索引实现,模拟文件共享服务的文件索引构建与检索功能。哈希表及其分布式变体如一致性哈希算法,保障文件均匀分布和负载均衡,持续优化文件共享服务性能。