剑指Offer39——数组中出现次数超过一半的数字

news2024/11/17 6:00:34

摘要

剑指Offer39 数组中出现次数超过一半的数字

本题常见的三种解法:

  • 哈希表统计法: 遍历数组 nums ,用 HashMap 统计各数字的数量,即可找出 众数 。此方法时间和空间复杂度均为 O(N) 。
  • 数组排序法: 将数组 nums 排序,数组中点的元素 一定为众数。
  • 摩尔投票法: 核心理念为 票数正负抵消 。此方法时间和空间复杂度分别为 O(N) 和 O(1) ,为本题的最佳解法。

一、哈希表统计法

1.1 哈希表统计法思路

我们知道出现次数最多的元素大于 n/2 次,所以可以用哈希表来快速统计每个元素出现的次数。
我们使用哈希映射(HashMap)来存储每个元素以及出现的次数。对于哈希映射中的每个键值对,键表示一个元素,值表示该元素出现的次数。

我们用一个循环遍历数组 nums 并将数组中的每个元素加入哈希映射中。在这之后,我们遍历哈希映射中的所有键值对,返回值最大的键。我们同样也可以在遍历数组 nums 时候使用打擂台的方法,维护最大的值,这样省去了最后对哈希映射的遍历。

图片.png

1.2 复杂度分析

  • 时间复杂度:O(n),其中 nn 是数组 nums 的长度。我们遍历数组 nums 一次,对于 nums 中的每一个元素,将其插入哈希表都只需要常数时间。如果在遍历时没有维护最大值,在遍历结束后还需要对哈希表进行遍历,因为哈希表中占用的空间为 O(n)。

  • 空间复杂度:O(n)。需要存储数组的相关元素到Hashmap中。

1.3 code 示例

/**
 * @description 利用Hashmap的方式的 时间O(n) 空间是O(n)
  * @param: nums
 * @date: 2022/12/7 9:30
 * @return: int
 * @author: xjl
*/
public int majorityElement(int[] nums) {
    HashMap<Integer, Integer> map=new HashMap<>();
    for (int i:nums){
        if (!map.containsKey(i)){
            map.put(i,1);
        }else {
            map.put(i,map.get(i)+1);
        }
    }
    for (int i:map.keySet()){
        if (map.get(i)>nums.length/2){
            return i;
        }
    }
    return -1;
}

二、数组排序法

2.1 数组排序的思路分析

如果将数组 nums 中的所有元素按照单调递增或单调递减的顺序排序,那么下标为 n/2的元素(下标从 0 开始)一定是众数。

对于这种算法,我们先将 nums 数组排序,然后返回上文所说的下标对应的元素。下面的图中解释了为什么这种策略是有效的。在下图中,第一个例子是 n 为奇数的情况,第二个例子是 n 为偶数的情况。

图片.png

对于每种情况,数组下面的线表示如果众数是数组中的最小值时覆盖的下标,数组下面的线表示如果众数是数组中的最大值时覆盖的下标。对于其他的情况,这条线会在这两种极端情况的中间。对于这两种极端情况,它们会在下标为 n/2的地方有重叠。因此,无论众数是多少,返回 n/2 下标对应的值都是正确的。

图片.png

2.2 数组的排序的复杂度分析

  • 时间复杂度:O(nlog⁡n)。将数组排序的时间复杂度为 O(nlog⁡n)。

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

2.3 code 示例

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

三、摩尔投票法

3.1 数组排序的思路分析

核心理念为 票数正负抵消 。设输入数组 nums 的众数为 x ,数组长度为 n 。

  • 推论一: 若记众数的票数为+1 ,非众数 的票数为−1,则一定有所有数字的票数和>0

  • 推论二:若数组的前a个数字的票数和 =0 ,则 数组剩余(n−a)个数字的 票数和一定仍>0 ,即后 (n−a)个数字的众数仍为x。

图片.png

根据以上推论,记数组首个元素为n1,众数为x,遍历并统计票数。当发生票数和=0时,剩余数组的众数一定不变,这是由于:

  • 当 n1=x:抵消的所有数字中,有一半是众数 x 。
  • 当 n1≠x:抵消的所有数字中,众数 x的数量最少为0个,最多为一半。

利用此特性,每轮假设发生 票数和=0都可以缩小剩余数组区间 。当遍历完成时,最后一轮假设的数字即为众数。

算法流程:

  • 初始化: 票数统计 votes = 0 , 众数 x;
  • 循环: 遍历数组 nums 中的每个数字 num ;
    • 当 票数 votes 等于 0 ,则假设当前数字 num 是众数;
    • 当 num = x 时,票数 votes 自增 1 ;当 num != x 时,票数 votes 自减 1 ;

3.2 数组的排序的复杂度分析

  • 时间复杂度 O(N) :NN 为数组 nums 长度。
  • 空间复杂度 O(1) :votes 变量使用常数大小的额外空间。

3.3 code 示例

/**
 * @description 使用摩尔投票的方式来实现 当前为 vote=0 时候 就认为当前是众数 然后判断 后面是否是该数 如果是+1 如果不是-1 当等于0的时候更新的该数字 最后的就是众数就是该数了。
  * @param: nums
 * @date: 2022/12/7 10:06
 * @return: int
 * @author: xjl
*/
public int majorityElement3(int[] nums) {
    int count=1;
    int result=nums[0];
    for ( int i=1;i< nums.length;i++){
        if (count==0){
           result=nums[i];
        }
        if (nums[i]==result){
            count++;
        }else {
            count--;
        }

    }
    return result;
}

博文参考

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python学习-8.1.1 标准库(time库的基础与实例)

2.1 time库 time库是Python提供的处理时间标准库。time库提供系统级精确计时器的计时功能&#xff0c;可以用来分析程序性能&#xff0c;也可以让程序暂停运行时间。 2.1.1 时间处理函数 time.time()函数&#xff1a;获取当前时间戳。 代表着如今的时间与1970年1月1日0分0秒…

18.10 字节码指令集与解析举例 - 同步控制指令

同步控制指令 组成 java虚拟机支持两种同步结构&#xff1a;方法级的同步和方法内部一段指令序列的同步&#xff0c;这两种同步都是使用monitor来支持的。 方法级的同步 方法级的同步&#xff1a;是隐式的&#xff0c;即无须通过字节码指令来控制&#xff0c;它实现在方法调…

Java+SSM网上书城全套含微信支付电商购物(含源码+论文+答辩PPT等)

项目功能简介: 本项目含代码详细讲解视频&#xff0c;手把手带同学们敲代码从0到1完成项目 该项目采用技术Springmvc、Spring、MyBatis、Tomcat服务器、MySQL数据库 项目含有源码、配套开发软件、软件安装教程、项目发布教程以及代码讲解教程 项目功能介绍&#xff1a; 系统管理…

HTML做一个简单的页面(纯html代码)地球专题学习网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

STM32F4 | 新建工程模板——寄存器版本 | HAL库入门 | 新建工程模板——库函数版本

文章目录一、新建工程模板——寄存器版本二、HAL入门1.固件库和寄存器的区别2.STM32CubeF43.HAL库包介绍三、新建HAL库工程模板一、新建工程模板——寄存器版本 开发环境&#xff1a;MDK5软件包&#xff1a;STM32CubeF4包 新建工程模板的一般步骤为&#xff1a; 新建工程目录&a…

【UE5】多用户协同编辑

UE5新出了一个多用户协同功能所以想搭一个来玩玩。 Epic已经将流程极度的简化了&#xff0c;在B站虚幻官方也放出了教程视频&#xff0c;[官方文档](多用户编辑入门 | 虚幻引擎文档 (unrealengine.com))也有教程。 这里做一下简要记录。 1.启用插件 首先打开Multi-User Edi…

SoftPerfect NetWorx中管理流量和宽带设备工具

SoftPerfect NetWorx中管理流量和宽带设备工具 NetWorx是用于在Windows中管理流量和宽带设备的简单工具和实用程序。如果我们利用交通设施&#xff0c;毫不拖延地利用教育系统&#xff0c;以及与各种驾驶员相关的学习&#xff0c;那么当加载互联网时&#xff0c;通过软件秘密使…

[附源码]计算机毕业设计酒店客房管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器

BaiqiSoft MstHtmlEditor for .NET负责编辑的控制器 BaiqiSoft MstHtmlEditor获取.NET for win表单被认为是一个元素,用户可以轻松灵活地将其融入到C#、VB.NET甚至WPF软件中。负责编辑的控制器,.NET Win Forms的MstHtmlEditor,允许用户和开发人员,甚至非技术用户使用该系列…

Docker入门第二期

写目一、宿主机与容器之间的文件拷贝二、数据卷三、数据卷容器四、Dockerfile一、宿主机与容器之间的文件拷贝 docker run -p 3307:3306 --name mysql1 -di -v /home/javaxl/data/mysql/mysql.conf.d/:/etc/mysql/mysql.conf.d/ -v /home/javaxl/data/mysql/data/:/var/lib/…

用Python把附近的足浴店都给采集了一遍,好兄弟:针不戳~

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的小编 又到了学Python时刻~ &#xff08;文末送读者福利&#xff09; 我又来了&#xff01;今天整个好玩的&#xff0c;你们肯定喜欢~ 咱们上班累了&#xff0c;不得好好犒劳一下自己&#xff0c;是吧 &#xff01; 于是我整…

相控阵天线(十三):天线校准技术仿真介绍之换相法

目录简介换相法算法简介换相法校准对方向图的影响Hadamard控制矩阵的换相法仿真循环移相控制矩阵的换相法仿真简介 传统方法按照测试区域分&#xff0c;可分为远场、中场和近场测量。远场测量发展成熟&#xff0c;可直接测量方向图&#xff0c;但对条件要求较高&#xff0c;且…

SpringMVC从入门到精通(二)

文章目录6. 响应视图和结果数据6.1 返回值类型6.2 springmvc作用域传值6.3 转发和重定向6.4 json数据格式的请求与响应7.SpringMVC 实现文件上传7.1 文件上传三要素7.2 文件上传依赖7.2 文件上传示例&#xff08;后端需要配置文件解析器&#xff09;8. SpringMVC 中的异常处理8…

FMT航点飞行(一)

一、航点飞行前检查&#xff1a; &#xff08;1&#xff09;将飞行器在position模式下启动飞行&#xff0c;移动一个距离&#xff1b;在qgc地面站地图上观察移动的距离&#xff0c;记录大概移动的距离为D&#xff1b;打航向&#xff0c;观察地磁计转向是否正常&#xff1b; &a…

Redisson的看门狗机制究竟有什么用?

Redisson的看门狗机制究竟有什么用&#xff1f; 一、普通的Redis分布式锁的缺陷 基于Redis的分布式锁 Redis Lua 脚本实现分布式锁 二、watchDog的自动延期机制 调用链关系 源码解析 tryLock() tryAcquire() tryAcquireAsync() scheduleExpirationRenewal() 锁…

Nginx+tomcat集群

Nginxtomcat集群 定义&#xff1a;在测试环境中有多个tomcat运行这一个项目&#xff0c;需要nginx管理 2特点&#xff1a;1&#xff0c;增加项目访问能力 2&#xff0c;增加服务器性能 3&#xff0c;实现不同负载均衡 3负载均衡&#xff1a;根据每台服务器的性能分配其能承受住…

【Linux】程序地址空间

目录 地址空间是什么 写时拷贝 地址空间存在的意义 如何管理进程地址空间 地址空间是什么 这是我们常说的c/c程序地址空间&#xff0c;但是这里的空间具体指的是哪里的空间&#xff0c;举一个例子方便理解&#xff1a; 运行结果&#xff1a; 代码运行十秒后子进程修改了全局…

目标检测—DiffusionDet:用于检测的概率扩散模型笔记—DDPM

目录 一、Introduction 二、相关工作 三、方法 1.准备工作 2.架构 3、训练 4.预测过程 四. 实验 1.训练策略 2.main property 3.消融实验 五、代码分析 1.测试 demo.py 2.训练 train-net.py 总结 DiffusionDet&#xff1a;将目标检测问题构建为一个从带噪框到目…

安卓APP源码和设计报告——麻雀笔记

目录 一 安卓应用程序开发背景3 1.1开发背景3 1.2开发环境4 二 安卓应用程序开发理论与方法4 三 记事本应用程序的设计与实现5 3.1 拟解决的问题及目标5 3.2 总体设计6 3.3 详细设计与编码实现6 四 总结23 一 安卓应用程序开发背景 1.1开发背景 1.智能手机的市场 …

四年一次的世界杯来了,看看还剩下哪些赛程呢?

足球世界杯的由来2022年的世界杯目前世界杯的赛程看看排在前十的球员几个疑问&#xff1f;世界杯的由来 足球大家应该知道&#xff0c;是一项体育运动&#xff0c;而且是一项多人的体育运动。 世界杯的诞生&#xff0c;源于1950年的南非公开赛&#xff0c;在当时只有5支队伍参…