【数据结构与算法精炼】LeetCode No.169 : Majority Element,由一道算法题想到的关于多数投票算法(Boyer-Moore Voting)的使用

摩尔投票算法原理&实现一文剖析 摩尔投票法(Boyer-Moore Voting Algorithm)是一种高效的算法,主要用于在数组中寻找出现次数超过一半的元素,即多数元素。该算法由Robert S. Boyer和J Strother Moore在1981年提出,其时间复杂度为O(n),空间复杂度为O(1),是处理这类问题的最优解法。本文我将为你详细介绍摩尔投票法的原理、实现及应用场景 阅读详情

引言

数据结构与算法,是程序员的内功修炼。甚至有开发者还提出了程序=数据结构+算法。
少侠我之前参加校招的时候,也是凭借在手撕代码环节出色的算法解题思路获得面试官的称赞并击败众多竞争者最后拿到字节跳动、搜狐等大厂的offer。
为了保持算法心经的日臻纯熟,我暗下决心,决定开始写互联网数据结构与算法相关的文章,希望能帮助各位读者在以后的手撕代码中游刃有余,对面试官进行360°的反击,让一同面试的同僚瞠目结舌,疯狂收割互联网大厂offer!
文章中虽然应用了夸张的修辞手法,但我们应该始终保持一颗谦逊的心。希望和大家怀着虚怀若谷的心态,共同学习进步。

问题描述

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exist in the array.

Example 1:

Input: [3,2,3]
Output: 3

Example 2:

Input: [2,2,1,1,1,2,2]
Output: 2

问题分析

这道题目题意很清晰:给定一整型数组,找到数组中出现次数大于数组长度一半的那个数字。
解读了题意之后,聪明的你是否立即有了思路、跃跃欲试呢?
在这里插入图片描述
对嘛,数组中有一半以上的数字都是它,不是排序之后索引在中间的那个数肯定就是所求了么,于是解法一呼之欲出,两行代码搞定。

解法一:Sorting

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

算法的时间复杂度O(nlog(n)),空间复杂度O(1)。性能较好。

当写到这里,你是不是还在自我陶醉,洋洋自得呢,快醒醒,这是大家都能想到的解法,而且是直接调用的数组工具类方法,难以在笔试中体现自我水平,想要从千百竞争者中脱颖而出,怎么能没有点东西呢?解法一只是为了抛砖引玉,解法二的多数投票算法才是本文的重点。

在这里插入图片描述

解法二:Boyer-Moore voting algorithm

1 Boyer-Moore 算法实现原理
Boyer-Moore需要记录两个值:候选节点candidate和count,核心在于要对给定数组进行两趟扫描。第一趟扫描我们得到一个候选节点candidate,第二趟扫描我们判断candidate出现的次数是否满足要求。

记录的值的初始化:
candidate,初值可以为任何数,这里可以就用数组的第一个元素;
count,初值为0

之后对于数组中每一个元素,首先判断count是否为0,若为0,则把candidate设置为当前元素。之后判断candidate是否与当前元素相等,若相等则count+=1,否则count-=1。

在第一趟扫描结束后,如果数组中存在多数元素,那么candidate即为其值,如果原数组不存在多数元素,则candidate的值没有意义。所以需要第二趟扫描来统计candidate出现的次数来判断其是否为多数元素。

这里,我们就用[1,2,2,1,1,2,2]这样一个数组为例演示Boyer-Moore算法的原理(通过观察我们知道2是多数元素)。算法流程如下图所示:
在这里插入图片描述按照上述流程,运行的结果如下图所示:

索引i0123456…
nums[i]1221122…
candidate1122112…
count1010101…

如上表所示,首先,candidate被设置为第一个元素1,count也变成1,由于1不是多数元素,所以当扫描到数组某个位置时,count一定会减为0。在本例中,当扫描到第二个位置时,count变成0。实际上cadidate的取值永远受上一步的count值决定。最后candidate=2(如果数组中存在多数元素,那么candidate即为其值,如果原数组不存在多数元素,则candidate的值没有意义。所以需要第二趟扫描来统计candidate出现的次数来判断其是否为多数元素)。

当count变成0时,对于每一个出现的1,我们都用一个0与其进行抵消,所以我们消耗掉了与其一样多的0,而0是多数元素,这意味着当扫描到第四个位置时,我们已经最大程度的消耗掉了多数元素。然而,对于数组从第五个位置开始的剩余部分,0依然是其中的多数元素(注意,多数元素出现次数大于⌊ n/2 ⌋,而我们扫描过的部分中多数元素只占一般,那剩余部分中多数元素必然还是那个数字)。如果之前用于抵消的元素中存在非多数元素,那么数组剩余部分包含的多数元素就更多了。
类似的,假设第一个数字就是多数元素,那么当count减为0时,我们消耗掉了与多数元素一样多的非多数元素,那么同样道理,数组剩余部分中的多数元素数值不变。
这两种情况证明了关键的一点:数组中从candidate被赋值到count减到0的那一段可以被去除,余下部分的多数元素依然是原数组的多数元素。我们可以不断重复这个过程,直到扫描到数组尾部,那么count必然会大于0,而且这个count对应的candinate就是原数组的多数元素。

2 Boyer-Moore 算法扩展:分布式应用
Boyer-Moore还有一个优点,那就是可以使用并行算法实现。
基本思想为对原数组采用分治的方法,把数组划分成很多段(每段大小可以不相同),在每段中计算出candidate-count二元组,然后得到最终结果。

举个例子,原数组为[1,1,0,1,1,0,1,0,0]
划分1:
[1,1,0,1,1] –> (candidate,count)=(1,3)
划分2:
[0,1,0,0] –> (candidate,count)=(0,2)
根据(1,3)和(0,2)投票结果可得,原数组的多数元素为1。

3 代码清单
通过上面的介绍,希望大家对Boyer-Moore有个清晰的认知,然后结合本题给出利用Boyer-Moore算法的解答,附程序清单:

class Solution {
    public int majorityElement(int[] nums) {
       int count = 0, res = 0;
        for (int num : nums) {
            if (count == 0) {
                res = num;
            }
            if (num != res) {
                count--;
            } else {
                count++;
            }
        }
        return res;
    }
}

当然本题还可以用HashMap解答,这里不做赘述。HashMap的原理传送门↓
【Java基础】HashMap底层实现原理 附源码分析及面试题,带你深入Java集合

小结

数据结构与算法,在实际开发中应用的可能并不多,但是掌握好这些知识点在面试、自我提升、对项目的认知是大有裨益的。优秀的算法不仅看着顺眼,用起来也是真香。数据结构与算法就好比是程序员的内功修炼,没有好的内功加持,再厉害的外家功夫也是花里胡哨。

点点关注,不会迷路

算法MAJORITY(寻找多数元素) 寻找多数元素。用递归算法MAJORITY实现多数的寻找,其中调用candidate(m)函数。 立即下载

相关推荐

macOS 27下PlayCover“没有权限打开”的完整修复指南

macOS系统通过Gatekeeper、TCC(透明、同意与控制)和安全启动等机制,对第三方应用进行层层校验,以防范恶意代码。这些机制会检查应用的隔离属性、签名状态以及所需系统权限,当任一环节不满足时,就会出现“没有权限打开”的提示。对于开发者工具或未上架App Store的开源软件,这类拦截尤为常见。尤其在macOS 27上,系统进一步收紧了绕过策略,导致PlayCover等工具无法正常启动。本文以PlayCover为例,详细解析权限链路上的三道关卡,并给出清除隔离属性、调整SIP状态、重置TCC记录等完

weixin_32612263的博客 744

摩尔投票算法(Boyer-Moore Voting Algorithm)

给定一个数组A,其中含有 n 个元素,在数组A中出现超过 n/2 次的元素,也就是出现次数超过 n/2 的众数。现在的问题要求找到数组中是否存在这样的元素,其出现次数超过 n/2。现在本文就来讨论在线性复杂度下,计算成本最优的算法。

BoCong-Deng的博客 1476

1G/2.5G Ethernet PCS/PMA or SGMII

SGMII即Serial GMII,串行GMII,收发各一对差分信号线,时钟频率625MHz,在时钟信号的上升沿和下降沿均采样,所以总的数据速率为1.25Gbps=625Mbps*2。参考时钟RX_CLK由PHY提供,是可选的,主要用于MAC侧没有时钟的情况,一般情况下,RX_CLK不使用。收发都可以从数据中恢复出时钟。在TXD发送的串行数据中,每8比特数据会插入TX_EN/TX_ER 两比特控制信息,同样,在RXD接收数据中,每8比特数据会插入RX_DV/RX_ER 两比特控制信息。

sqzjiayou的博客 1万+

Boyer-Moore算法:多数投票算法(majority voting algorithm)

这里的count代表的就是当前的candidate与其他元素之间出现次数的差距的绝对值,最后的candidate就是所找出的出现次数最多的元素(众数,也可以想成是得票最多的人)。上述过程与下面的动画所示是一致的。众数(majority element)的数目必须。时,count就增加1;的时候,candidate更新为。遍历数组,当遍历到的数组元素。时,count就减1;证明过程可以参考论文。

博客简介 1003

【零基础入门哈希签名架构,从Lamport到SPHINCS+】第二集 哈希签名树 Merkle Tree Authentication

在第一集中,我们一直忽略了一个问题。设想一下,假如有一个Hacker(黑客),在截获到Sender发送给Receiver的公钥之后,把这个公钥改成Hacker自己的公钥,然后再发给Receiver,那么Receiver就会误认为这是Sender的公钥。所以我们之前所说放方案,其安全性都需要建立在一个前提下:Receiver需要确认公钥确实是Sender发出的。

m0_50572808的博客 2453

化工设计软件:AutoCAD Plant 3D二次开发_(1).AutoCADPlant3D概述

AutoCAD Plant 3D 是一款专为化工行业设计的三维工厂设计和建模软件。它基于AutoCAD平台,提供了强大的三维建模功能和专业的化工设计工具,帮助工程师和设计师在工厂设计过程中提高效率和准确性。AutoCAD Plant 3D不仅能够创建详细的三维模型,还可以进行管道设计、设备布置、支架设计等复杂任务。通过上述案例,我们可以看出 AutoCAD Plant 3D 在化工厂设计中的强大功能和优势。该软件不仅提供了丰富的建模工具和专业的设计功能,还支持二次开发,使用户能够根据具体需求进行定制化操作。

kkchenjj的博客 1103

Boyer-Moore 投票算法

在计算机科学中,寻找数组中的多数元素(即出现次数超过一半的元素)是一个经典问题。Boyer-Moore 投票算法(Boyer-Moore Voting Algorithm)是一种高效且优雅的解决方案,能够在时间复杂度为 O(n) 和空间复杂度为 O(1) 的情况下找到多数元素。Boyer-Moore 投票算法的核心思想是通过“投票”和“抵消”的过程来找到多数元素。假设我们有一个长度为 n 的数组,我们需要找到其中出现次数超过一半的元素。:遍历完成后,当前的候选人就是出现次数超过一半的元素。

c_studer_的博客 909

SMOKE 3D:从 Python 到 C++ 实现车辆与行人单目 3D 视觉识别在 RK3588 上的深度部署

SMOKE的网络结构通常基于高性能的骨干网络(如DLA-34,您使用的模型就是基于此),通过编码器-解码器架构来提取特征。输入:RGB图像(本项目为骨干网络:用于特征提取。检测头热力图分支:预测关键点热力图。通常在热力图上进行NMS来找到局部最大值,即潜在的关键点位置。回归分支:对于每个关键点位置,预测上述的8维3D属性向量。分类分支:预测每个关键点对应的物体类别。置信度分支:预测每个关键点的置信度。本教程详细介绍了SMOKE单目3D目标检测模型在RK3588上的部署。我们从SMOKE的。

LXY_LOVE36的博客 437

LeetCode 169. Majority Element 题解

题目描述: 169. Majority Element   Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the a

daqiang95的博客 450

车载以太网-TC8测试

TC8测试的用例数量 TC8测试基本流程 TC8测试内容

天赐好车的博客 3618

基于Simulink雷达系统建模仿真(附源码)

此示例显示如何设置由发射器、带目标的信道和接收器组成的雷达系统仿真。一、系统架构该系统包括:雷达脉冲发生器,以 2% 占空比(导通时间 = 2 ms,周期 = 100 ms)输出功率为 1 mW 的啁啾声。RF发射器部分由滤波器和组成,使用RF模块集电路包络库模块实现。由于滤波器是线性器件,放大器是非线性器件,因此它们被分成两个独立的子系统。这种分离允许在每个子系统中使用不同的仿真频率集。这种分离还允许在更快的仿真速度和级联链中可用的级间负载效应损失之间进行权衡。

珞瑜的博客 4581

【小白笔记】多数元素 (Majority Element), 摩尔投票法 (Boyer-Moore Voting Algorithm)。

优先级代码条件逻辑解释(投票)高重新开始:领跑者被清零,推选新人 (count = 1中支持加票:当前元素是领跑者本人 (count += 1低反对抵消:当前元素是反对票 (count -= 1通过这种**“零票重置 -> 自己加票 -> 别人减票”** 的流程记忆,能轻松重现摩尔投票法的代码逻辑了。扩展/变种题:LeetCode 229. 多数元素 II (Majority Element II)找到数组中所有出现次数大于⌊n3⌋⌊n/3⌋的元素。这是摩尔投票法的变种。需要设置k。

weixin_70325224的博客 683

详解FreeRTOS:事件标志组(高级篇—5)

事件组可以实现一对多,多对多的同步,即一个任务可以等待多个事件的发生。任务可以通过设置事件位来实现事件的触发和等待操作,FreeRTOS的事件仅用于同步,不提供数据传输功能。

不脱发的程序猿 1075

LeetCode 169. Majority Element(Boyer-Moore Voting)

链接:https://leetcode.com/problems/majority-element/ 思路 Approach 1: 迭代nums,用map记录各值出现的次数,再迭代map,次数大于size/2的即majority element。 Approach 2: Boyer-Moore Voting。基本原理:假设某混合物中,某物质M含量p1,从中分离出一部分,离开部分M的含量p2 &lt...

zjj1149的博客 276

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

LeetCode-169. Majority Element

169. Majority Element 题目 Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and t...

家行hang的博客 274

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

LeetCode 169. Majority Element

题目描述:找出一个数组中的众数,众数出现的次数大于 [n/2]大于一般的次数这个信息很关键,可以有很多做法,参照solution做法。 题目链接:LeetCode 169. Majority Element 我用了很作弊的手段。 return Counter(nums).most_common()[0][0] return max(Counter(nums),key=Counter(num...

Za七杂⑧ 152

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

169. Majority Element(C++ 和 Java解法)

本小白华中科技大学在读研究生,自然语言处理方向。现每日一更LeetCodeTop 100 Liked Questions, 旨在于通过通俗易懂的画风和诸位计算机朋友们一起成长呀,不局限某题,争取举一反三,所有Questions均呈上C++和Java解法,不足之处多多指正,共同学习。 这种题目要熟练掌握数据结构,类似题见Top K Frequent Elements 解题思路一: 首先想到利用map,key代表元素值,value代表元素出现的次数,因为题目保证总有一个元素出现次数大于n/2,所...

m0_37536878的博客 247

Leetcode #169 Majority Element

问题描述: Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority

小昕成长史 242

LeetCode 229. Majority Element II ,169. Majority Element

题目链接:https://leetcode.com/problems/majority-element-ii/ 题目描述: Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. The algorithm should run in linear time

yxy 478

(算法设计技巧与分析)Majority

#include using namespace std; int Condidate(int a[],int n,int j); int main() { int count=0; int a[12]={1,1,1,1,1,1,2,2,2,2,2,2}; int c=Condidate(a,12,0); for(int i=0;i<12;i++) if(a[i]==c) cou

lonely_Quan的专栏 1309

算法分析与设计第五次作业(leetcode 中 Majority Element 题解)

心得体会 这个题目有两个版本Majority Element,和Majority Element II,标记都表示hard,但是我自己觉得不简单,所以就写下来

ousuixin的博客 640

LintCode majority numbe (主元素)

LintCode 主元素主元素 给定一个整型数组,找出主元素,它在数组中的出现次数严格大于数组元素个数的二分之一。给出数组[1,1,1,1,2,2,2],返回 1 挑战 要求时间复杂度为O(n),空间复杂度为O(1) 。solution: 对于这个问题,有很多解决的方法。Method1. 最基本的解决方法 使用两个for循环计算出每个元素出现的次数, 如果该次数大于数组元素的二分之一就返回

david_liang 1023

Boyer-Moore Majority Vote Algorithm的更一般性问题

1) 问题描述基本问题:对于一个给定数组A[0:n-1],找出出现次数大于⌊n/2⌋\lfloor n/2\rfloor 的元素,称为Majority element. 一般问题:对于一个给定数组A[0:n-1],找出出现次数大于⌊n/k⌋(k≥2)\lfloor n/k\rfloor( k\ge2)的所有元素.LeetCode问题链接: Majority Element: https://le

isunn的专栏 2168

算法整理:Boyer-Moore 投票算法

1,基本思想 Boyer-Moore 投票算法的基本思想是:在每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。 如果数组为空,则数组中不存在主要元素; 如果数组中剩下的元素都相等,则数组中剩下的元素可能为主要元素。(可能的原因是,如果是这样的一个数组[1,2,3],那么剩下的元素是3,但是3并不是数量超过一半的元素。) 2,主要步骤 Boyer-Moore 投票算法的步骤如下: 维护一个候选主要元素 candidate 和候选主要元素的

qq_40206371的博客 2935

摩尔投票算法( Boyer-Moore Voting Algorithm)

摩尔投票算法也可以叫做多数投票算法,是我在看到 leetcode 169(Majority Element)题目时看到的算法。这篇文章从 leetcode 169(Majority Element)出发讲解摩尔投票算法的原理和优势,同时从 leetcode 229(Majority Element2)出发讲解摩尔投票算法的改进和推广。(本文所有代码都是python代码) 一、Majority E

yeal 1万+

Boyer-Moore Voting算法

Leetcode 169.Majority Element Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is n...

Adam_allen的博客 891
上一篇: 【数据结构与算法精炼】LeetCode No.136 : Single Number,由一道算法题想到的关于XOR运算的使用
下一篇: 高并发下接口幂等性解决方案
少侠露飞
博客等级 码龄9年 214粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值