摩尔投票算法原理实现一文剖析

article/2025/6/19 4:51:09

摩尔投票算法原理&实现一文剖析

    • 一、算法原理
      • 1.1 基本思想
      • 1.2 数学原理
    • 二、算法实现
      • 2.1 Python实现
      • 2.2 Java实现
      • 2.3 C++实现
    • 三、复杂度分析
    • 四、应用场景
      • 4.1 多数元素问题
      • 4.2 扩展应用:寻找出现次数超过n/3的元素
    • 五、算法优势与注意事项
      • 5.1 优势
      • 5.2 注意事项
    • 总结

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

一、算法原理

1.1 基本思想

摩尔投票法的核心思想是基于这样一个观察:如果一个元素在数组中出现次数超过一半,那么该元素的出现次数一定比其他所有元素的出现次数总和还要多。

算法通过维护两个变量来实现:

  • 候选元素(candidate):记录当前可能的多数元素
  • 计数(count):记录候选元素的相对出现次数

算法的执行过程可以分为两个阶段:

  1. 投票阶段:遍历数组,对每个元素进行投票。如果当前元素与候选元素相同,则计数加1;否则计数减1。当计数减为0时,更换候选元素为当前元素,并将计数重置为1。
  2. 验证阶段:遍历结束后,得到的候选元素需要再次验证是否真的出现次数超过一半(在某些题目中,可能需要这一步骤,但在明确存在多数元素的情况下可以省略)。

1.2 数学原理

假设数组长度为n,多数元素出现次数为m(m > n/2)。在投票过程中,每当遇到一个非候选元素时,计数减1,但由于多数元素的出现次数超过一半,即使每次遇到非候选元素都抵消一次,最终候选元素的计数仍会大于0。因此,最终得到的候选元素必然是多数元素。
摩尔投票法

二、算法实现

2.1 Python实现

def majorityElement(nums):"""摩尔投票法实现,寻找数组中出现次数超过一半的元素"""# 初始化候选元素和计数candidate = Nonecount = 0# 投票阶段for num in nums:if count == 0:# 当计数为0时,更换候选元素为当前元素candidate = numcount = 1elif num == candidate:# 当前元素与候选元素相同,计数加1count += 1else:# 当前元素与候选元素不同,计数减1count -= 1# 验证阶段(在明确存在多数元素的情况下可以省略)# 这里简单验证候选元素的出现次数是否超过一半count = 0for num in nums:if num == candidate:count += 1if count > len(nums) // 2:return candidateelse:return None  # 实际上题目保证存在多数元素,不会执行到这一步# 示例用法
nums = [2, 2, 1, 1, 1, 2, 2]
print("多数元素是:", majorityElement(nums))  # 输出: 2

2.2 Java实现

public class BoyerMooreVoting {public static int majorityElement(int[] nums) {// 初始化候选元素和计数int candidate = 0;int count = 0;// 投票阶段for (int num : nums) {if (count == 0) {candidate = num;count = 1;} else if (num == candidate) {count++;} else {count--;}}// 验证阶段(在明确存在多数元素的情况下可以省略)count = 0;for (int num : nums) {if (num == candidate) {count++;}}if (count > nums.length / 2) {return candidate;} else {return -1;  // 实际上题目保证存在多数元素,不会执行到这一步}}public static void main(String[] args) {int[] nums = {2, 2, 1, 1, 1, 2, 2};System.out.println("多数元素是: " + majorityElement(nums));  // 输出: 2}
}

2.3 C++实现

#include <iostream>
#include <vector>
using namespace std;int majorityElement(vector<int>& nums) {// 初始化候选元素和计数int candidate = 0;int count = 0;// 投票阶段for (int num : nums) {if (count == 0) {candidate = num;count = 1;} else if (num == candidate) {count++;} else {count--;}}// 验证阶段(在明确存在多数元素的情况下可以省略)count = 0;for (int num : nums) {if (num == candidate) {count++;}}if (count > nums.size() / 2) {return candidate;} else {return -1;  // 实际上题目保证存在多数元素,不会执行到这一步}
}int main() {vector<int> nums = {2, 2, 1, 1, 1, 2, 2};cout << "多数元素是: " << majorityElement(nums) << endl;  // 输出: 2return 0;
}

三、复杂度分析

  • 时间复杂度:O(n),算法只需遍历数组两次(投票阶段一次,验证阶段一次),每次遍历的时间复杂度均为O(n)。
  • 空间复杂度:O(1),只需要常数级的额外空间来存储候选元素和计数。

四、应用场景

4.1 多数元素问题

摩尔投票法最典型的应用是解决LeetCode上的"多数元素"问题(题目编号169):给定一个大小为n的数组,找到其中的多数元素。多数元素是指在数组中出现次数大于⌊n/2⌋的元素。

4.2 扩展应用:寻找出现次数超过n/3的元素

摩尔投票法可以扩展用于寻找数组中出现次数超过n/3的元素(LeetCode题目编号229)。此时需要维护两个候选元素和对应的计数,基本思想类似,但在投票阶段需要更复杂的逻辑处理。

def majorityElement(nums):"""寻找数组中出现次数超过n/3的元素"""if not nums:return []# 初始化两个候选元素和计数candidate1, candidate2 = None, Nonecount1, count2 = 0, 0# 投票阶段for num in nums:if num == candidate1:count1 += 1elif num == candidate2:count2 += 1elif count1 == 0:candidate1 = numcount1 = 1elif count2 == 0:candidate2 = numcount2 = 1else:count1 -= 1count2 -= 1# 验证阶段result = []threshold = len(nums) // 3for candidate in [candidate1, candidate2]:if nums.count(candidate) > threshold:result.append(candidate)return result# 示例用法
nums = [3, 2, 3]
print("出现次数超过n/3的元素:", majorityElement(nums))  # 输出: [3]

五、算法优势与注意事项

5.1 优势

  • 高效性:时间复杂度O(n)和空间复杂度O(1)使其成为处理大规模数据的理想选择。
  • 简洁性:算法逻辑简单,代码实现简洁,易于理解和维护。

5.2 注意事项

  • 前提条件:摩尔投票法要求数组中一定存在多数元素。如果题目没有明确这一点,必须进行验证阶段,否则可能得到错误结果。
  • 扩展性:虽然可以扩展到寻找出现次数超过n/k的元素,但随着k的增大,算法复杂度和代码实现难度也会增加。

总结

摩尔投票法是一种优雅且高效的算法,特别适合解决寻找数组中多数元素的问题,其核心思想是通过抵消不同元素的出现次数,最终找到出现次数超过一半的元素,该算法不仅时间效率高,而且空间需求极低,是处理大规模数据的有力工具。

但需要注意的是,使用该算法时必须确保题目满足存在多数元素的前提条件,否则需要进行额外的验证步骤。希望通过我在本文的描述,你能够深入理解摩尔投票法的原理和应用,并在实际编码中灵活运用这一算法。

That’s all, thanks for reading!
觉得有用就点个赞、收进收藏夹吧!关注我,获取更多干货~


http://www.hkcw.cn/article/ytPuybxQZU.shtml

相关文章

私家车让行反被救护车司机竖中指!

私家车让行反被救护车司机竖中指。6月2日18时24分,四川成都绕城高速一辆新Q牌照救护车向一辆私家车竖中指,后经协商救护车方领导道歉并处理司机。私家车让行反被救护车司机竖中指私家车让行反被救护车司机竖中指私家车让行反被救护车司机竖中指责任编辑:0882

刘浩存三重人格杀疯了,国产剧该有的疯批美学

在仙侠剧沉迷于“五毛特效”的2025年,优酷带着《七根心简》横空出世,用七根封印上古凶煞的战国木简撕开娱乐圈的虚假繁荣。这部由宋威龙、刘浩存主演的奇幻冒险剧,将《山海经》神秘学与硬核探案熔于一炉,当木代(刘浩存饰)在预告片中徒手撕开凶简寄生体时,这场跨越千年的…

山东200家景区纳客839.5万 文旅消费显著增长

端午假期结束,山东省文化和旅游厅数据显示,全省文旅市场秩序井然、运转良好。重点监测的200家旅游景区接待游客839.5万人次,同比增长10.9%,营业收入达3.5亿元,同比增长9.4%。公共文化场馆共服务215.27万人次,同比增长15.34%。济南市红叶谷景区推出“22℃森林避暑季”寻找…

泽连斯基大骂俄代表“白痴” 停火只为收拾尸体?

6月2日,俄罗斯和乌克兰在土耳其伊斯坦布尔就和平解决俄乌冲突举行了第二轮直接谈判。乌方此前已向俄罗斯递交了有关停火立场的文件,俄方当天也公布了“乌克兰冲突解决备忘录”。俄罗斯代表团团长、总统助理梅金斯基在谈判后的新闻发布会上表示,俄方提议在前线特定区域暂时停…

端午假期青岛地铁上演温暖故事 温情守护传递城市温度

端午假期青岛地铁上演温暖故事 温情守护传递城市温度。端午佳节,粽叶飘香,艾草芬芳。当人们沉浸在阖家团圆、出游踏青的喜悦中,青岛这座海滨城市的“地下动脉”——地铁网络,正承载着万千乘客市民的归心与向往。端午节前一晚,一位女士焦急地向西海岸快线董家口火车站保安求…

长和股价日内涨超5% 港口交易引关注

长和股价日内涨超5% 港口交易引关注。长和(0001.HK)股价上涨5.58%,达到46.35港元。据英国《金融时报》报道,航运公司MSC与贝莱德最近几周与中国当局进行了面对面会谈,讨论与长和的港口交易,以缓解美国与中国因巴拿马运河产生的紧张关系。双方正在探讨确保中国监管机构批准交…

网传黄多多将出演《边城》翠翠一角 网友:一出来就是大饼啊!

黄多多有饼了,《边城》里面的翠翠!一出来就是大饼啊!责任编辑:zx0002

央视走进宜春熊出没乐园 童真欢乐齐绽放

央视走进宜春熊出没乐园 童真欢乐齐绽放!宜春熊出没乐园在6月1日儿童节当天迎来了中央广播电视总台央视频栏目组,他们不仅与熊大、熊二等明星家族欢乐互动,还体验了夏日限定的“萌熊雪糕节”甜蜜派对。活动通过实时传递乐园的童真趣味与节日狂欢,带领观众开启了一段“六一”…

华南等地强降雨持续 局地伴有强对流天气

今明两天,我国降雨主要出现在云南和华南沿海、东北地区等地,局地还可能伴有强对流天气。随着高压脊东移,北方大部气温逐渐升高,华北、黄淮等地高温天气将发展增多,南方多地5日起也将加入高温行列。昨天,南方强降雨区域南压至华南和云南一带;在北方,内蒙古东部和东北地区…

Gartner《Emerging Patterns for Building LLM-Based AIAgents》学习心得

一、AI代理概述 2024年,AI代理成为市场热点,它们能自主规划和行动以实现用户目标,与仅能感知、决策、行动和达成目标的AI助手及聊天机器人有本质区别。Gartner定义的AI代理是使用AI技术在数字或物理环境中自主或半自主运行的软件实体。 二、LLM基础AI代理的特性和挑战 优势…

【证书】2025上海市人工智能训练师—高级/三级考试介绍与复习(SJTU版)

【证书】2025上海市人工智能训练师—高级/三级考试介绍与复习&#xff08;SJTU版&#xff09; 文章目录 1、考试介绍2、考试复习2.1 理论知识2.2 实践知识 1、考试介绍 职业定义 1 标准名称&#xff1a;人工智能训练师国家职业编号&#xff1a;4-04-05-05职业内容&#xff1a…

徐志胜李嘉琦倒班陪蔡文静唠嗑 网友:这聊天内容我能蹲一晚上!

救命!蔡文静聊天魅力太大,徐志胜搞出“倒班陪聊制”,这聊天内容我能蹲一晚上!责任编辑:zx0002

为何俄对乌偷袭反应远低于预期?

为何俄对乌偷袭反应远低于预期。据美国《新闻周刊》网站6月1日报道,1日,41架俄罗斯战机遭乌克兰无人机突袭后,一些评论人士在网上称之为“俄罗斯的珍珠港事件”。报道称,这次袭击促使俄罗斯军事专家要求对乌克兰作出强烈而迅速的反应,包括如军事博主罗曼阿廖欣在“电报”社…

小车冲进店姐姐救回1岁妹妹 惊险瞬间化险为夷

6月2日,河南周口一家餐馆内发生了一起惊险事件。一辆小车突然撞进餐馆,直奔墙边的一个小女孩。就在小车即将撞上的一瞬间,她的姐姐迅速抱走了她。小车最终撞到墙上停下,两名女孩幸免于难。据餐馆老板介绍,视频中的两个女孩是他的孙女,姐姐11岁,妹妹只有1岁5个月。肇事司…

老外对端午节了解多少?端午节,我们在上海街头问了外国人这个问题

端午节来了,对于这个中国传统节日,在上海生活的外籍人士和远道而来的外国游客了解多少?带着这份好奇,我们走上上海街头,对“歪果仁”进行了一场随机采访。听说过端午吗,老外的反应是……在街访中,不管是初次来华的游客,还是从小在中国长大的“中国通”,对端午节的印象…

我国GDP五百亿镇近20个!

我国GDP五百亿镇近20个。今年是“十四五”收官之年,经过五年发展,我国镇域经济发展取得积极进展。镇域经济作为国民经济的最小单元,在国民经济体系中占据了基础位置。目前国内建制镇数量超过2万个,“十四五”期间,随着我国经济高质量发展,镇域经济也在不断壮大,截至2024…

蒙古国现在最大的特色是什么?

蒙古国现在最大的特色是什么?蒙古国作为草原文化与现代转型交织的国家,其当前最大的特色可从自然风貌、文化传承、社会现象及国际角色等多维度呈现:一、自然与游牧文化底色广袤草原与游牧生活蒙古国以辽阔的草原景观为核心特色,保留着传统游牧生活方式。游客可体验骑马驰骋…

24岁台大学生暗网贩毒被捕 涉案金额超7亿

美国联邦调查局近日破获了暗网毒品交易平台“隐身市场”,其经营者“法老”的真实身份是24岁的台湾大学资讯管理学系毕业生、台湾地外事替代役男子林睿庠。林睿庠涉嫌经营暗网向全球市场贩毒,3年多时间里非法所得超过1亿美元。他原定于去年7月4日退伍,却在5月18日在纽约机场过…

韩国选民表达对新总统期待 聚焦未来发展

当地时间6月3日6时,韩国第21届总统选举正式开始投票。投票时间从早上6时持续到晚上8时,共计14个小时。根据韩国中央选举管理委员会的数据,截至当天下午3时,投票率已达68.7%,投票总人数突破了3000万人。在投票现场,许多选民表达了对新总统的期待。一位当地民众表示,希望新…

上海口岸免签入境115万人次 南美五国游客享便利

上海口岸免签入境115万人次 南美五国游客享便利!6月2日,外籍游客在上海市第一食品商店(南东店)选购商品。自6月1日起,中国对巴西、阿根廷、智利、秘鲁、乌拉圭五个南美国家持普通护照人员试行单方面免签政策。至此,适用单方面免签政策来中国的国家已扩展至43个。据上海边检…