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

news2024/9/24 10:25:41

多数元素

今天的题目是力扣面试经典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;
        // 定义存储出现次数的map
        Map<Integer, Integer> map = new HashMap<>();
        for (int num : nums) {
            // 当前元素出现的次数,未出现过为0
            Integer 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.coloradmin.cn/o/1993316.html

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

相关文章

ESP32开发板单向点对点ESP-NOW无线通信

ESP32开发板单向点对点ESP-NOW无线通信 简介读取ESP32接收方Receiver的MAC地址ESP32发送方Sender程序ESP32接收方Receiver程序ESP-NOW通信验证总结 简介 本例程通过两个ESP32开发板实现单向点对点ESP-NOW无线通信&#xff0c;一个ESP32开发板作为Sender发送方&#xff0c;另一…

CSP-J复赛 模拟题6 解析

此题为水题不讲解 根据无解析写代码1&#xff1a; #include <bits/stdc.h> using namespace std; string s; int main(){getline(cin,s);int lens.length();for(int i0;i<len;i){if(s[i]>A && s[i]<Z){s[i]32;}else if(s[i]>a && s[i]<z…

python自动化笔记:配置文件.ini及yml文件

目录 一、.ini配置文件1.1、ini编写格式1.2、读取.ini配置文件的数据1.3、编辑&#xff1a;写入和删除&#xff08;了解即可&#xff09; 二、yaml文件2.1、yaml编写语法规则2.2、yaml三种数据结构2.3、yaml文件的读取和写入 一、.ini配置文件 后缀名.ini 用于存储项目全局配置…

【单片机开发软件】使用VSCode开发STM32环境搭建

&#x1f48c; 所属专栏&#xff1a;【单片机开发软件技巧】 &#x1f600; 作  者&#xff1a; 于晓超 &#x1f680; 个人简介&#xff1a;嵌入式工程师&#xff0c;专注嵌入式领域基础和实战分享 &#xff0c;欢迎咨询&#xff01; &#x1f496; 欢迎大家&#xff1…

随笔-见字如面

不出意外&#xff0c;7月的工时干成了部门第一&#xff0c;36个人天。 昨天洗头的时候&#xff0c;揉了两下头发&#xff0c;看了一眼&#xff0c;手里全是碎发&#xff0c;吓了一跳&#xff0c;赶紧冲掉了&#xff0c;这内力又精进了。最近加班有些疲惫了&#xff0c;总是感觉…

MySQL笔记(十):MySQL管理

一、用户管理 #用户管理 -- 原因&#xff1a;当我们做项目开发时&#xff0c;可以根据不同的开发人员&#xff0c;赋给她相应的mysql操作权限。 -- 所以&#xff0c;mysql数据库管理人员&#xff08;root&#xff09;&#xff0c;根据需要创建不同的用户&#xff0c;赋给相应的…

SparkSQL中的JSON内置函数全解析

SparkSQL中的JSON函数快速入门 目录 SparkSQL中的JSON函数快速入门为什么需要JSON函数?SparkSQL JSON函数概览get_json_object: JSON字段提取利器json_tuple: 多字段提取神器from_json: JSON转结构化数据的桥梁to_json: 结构化数据转JSON的便捷工具schema_of_json: JSON Schem…

加密创投周期进化论(上篇):再造新世界

回到过去&#xff0c;选择决定命运。 作者&#xff1a;Wenser&#xff1b;编辑&#xff1a;郝方舟 出品 | Odaily星球日报&#xff08;ID&#xff1a;o-daily&#xff09; 2017 年 12 月&#xff0c;以太坊联创 Vitalik 在加密货币行业市值触及 5000 亿美元时&#xff0c;发出了…

C语言程序设计-[8] while语句循环结构

1、while语句循环结构定义 while语句循环结构的一般形式、流程图和执行过程如下&#xff1a; 注1&#xff1a;与前面一样&#xff0c;表达式可以是任意的&#xff0c;只要有值就行&#xff0c;遵循非0即真的原则。 注2&#xff1a;一个循环结构由四个要素构成&#xff1a;循环…

【漏洞复现】某赛通电子文档安全管理系统 NavigationAjax SQL注入漏洞

0x01 产品简介 某赛通电子文档安全管理系统&#xff08;简称&#xff1a;CDG&#xff09;是一款电子文档安全加密软件&#xff0c;该系统利用驱动层透明加密技术&#xff0c;通过对电子文档的加密保护&#xff0c;防止内部员工泄密和外部人员非法窃取企业核心重要数据资产&…

【机器学习】Caltech-101的基本概念和使用方法以及Caltech-101和ImageNet的联系和区别

引言 Caltech-101数据集是一个广泛用于对象识别任务的数据库&#xff0c;它包含了大约9,000张图像&#xff0c;这些图像来自101个不同的对象类别。每个类别包含的图像数量大约在40到800张之间&#xff0c;大多数类别大约有50张图像。图像的分辨率大致为300200像素 文章目录 引言…

sleuth+zipkin分布式链路追踪

概述 结构图 常见的链路追踪 cat zipkin pinpoint skywalking sleuth Sleuth介绍 Trace Span Annotation 使用Sleuth 添加依赖 <!--sleuth--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starte…

DSL domain specific language of Kola

How we design Kola - ApiHugKola background, Kola a consumer driver tester frameworkhttps://apihug.com/zhCN-docs/kola/003_dsl_contract Concept 在 Kola 定位中 Kola 是什么, 是致力于提供一个让相关各方都能够理解共同创造的测试框架和工具。 同时 Kola 是建立于业界…

AcWing双链表

0索引记录头结点&#xff0c;1索引是尾节点&#xff0c;idx从2开始记录 L和R是前面的索引和后面索引的数组&#xff0c;e是存储的元素的数组&#xff0c;k1的原因&#xff1a;k是表示第k个插入的元素&#xff0c; k ∈ [ 1 , inf ⁡ ] k\in [1,\inf] k∈[1,inf].但是 i d x ∈ …

卷爆大模型,引发硅谷大厂打擂台赛的AI Agent到底是何方神圣?

AI Agent是何方神圣&#xff1f; 让比尔盖茨在2023年预言&#xff1a;未来五年内有望正式迎来它&#xff0c;彻底改变人类的生产力与生活方式。 让吴恩达教授在AI Ascent 2024演讲中高赞&#xff1a;今年得益于它的工作流的帮助&#xff0c; 人工智能的能力范围将持续拓展&am…

VBA经典应用69例应用6:Range.NumberFormat属性

《VBA经典应用69例》&#xff08;版权10178981&#xff09;&#xff0c;是我推出的第九套教程&#xff0c;教程是专门针对初级、中级学员在学习VBA过程中可能遇到的案例展开&#xff0c;这套教程案例众多&#xff0c;紧贴“实战”&#xff0c;并做“战术总结”&#xff0c;以便…

2023年中国城市统计年鉴(PDF+excel)

2023年中国城市统计年鉴 1、时间&#xff1a;1985-2023年 2、格式&#xff1a;PDFexcel 3、说明&#xff1a;中国城市统计年鉴收录了全国各级城市社会经济发展等方面的主要统计数据&#xff0c;数据来源于各城市的相关部门。本年鉴内容共分四个部分&#xff1a;第一部分是全…

HDFS 之 文件流

org.apache.hadoop.hdfs.DFSInputStream read 接口的关键逻辑在以下 pread 接口。 private int pread(long position, ByteBuffer buffer)throws IOException {// sanity checksdfsClient.checkOpen();if (closed.get()) {throw new IOException("Stream closed");}…

24/8/8算法笔记 决策树构建鸢尾花

决策树是一种由算法自动设计的模型。在机器学习中&#xff0c;构建决策树的过程通常遵循以下步骤&#xff1a; 特征选择&#xff1a;算法会评估每个特征&#xff0c;并选择一个特征作为节点分裂的依据。这个选择基于某种准则&#xff0c;如信息增益&#xff08;ID3算法&#xf…

手把手教你去掉WinRAR中的广告?

你是否在使用WinRAR的时候&#xff0c;打开压缩包的时候&#xff0c;它就会给你弹出一个广告窗口&#xff0c;是不是很烦人。本章教程&#xff0c;教你如何将它去除掉。 1、下载所需软件 通过百度网盘分享的文件&#xff1a;reshacker 链接&#xff1a;https://pan.baidu.com/s…