摩尔投票法详解
一、摩尔投票法是什么
摩尔投票法是一种高效的线性时间、常数空间算法,专门用于求解 无序数组中出现次数超过 n/2 的元素(也叫绝对众数),同时可以扩展到求解出现次数超过 n/k 的元素。 核心优势:
- 时间复杂度:O(n),仅需一次遍历数组;
- 空间复杂度:O(1),无需额外哈希表存储元素频次,极致优化。 补充说明:该算法的核心逻辑基于一个数学事实——在任何数组中,绝对众数的出现次数比其他所有元素的总和还多,这是算法能成立的根本前提。
二、算法核心思想
摩尔投票法的核心可以拆解为 「抵消」和「计数」 两个关键步骤,逻辑极其简洁:
- 抵消阶段:遍历数组时,维护一个候选众数
candidate和一个计数变量count。- 如果
count == 0,说明当前没有候选众数,将当前元素设为candidate; - 如果当前元素 ==
candidate,则count += 1(候选众数的支持数 +1); - 如果当前元素 !=
candidate,则count -= 1(不同元素两两抵消,支持数 -1)。
- 如果
- 验证阶段(可选但建议必做):遍历结束后,得到的
candidate只是可能的众数,需要再次遍历数组,统计其真实出现次数,确认是否超过 n/2。- 原因:如果数组中不存在绝对众数,算法也会返回一个候选值,必须验证才能保证结果正确。
核心原理拆解
算法的本质是利用「多数元素的压倒性优势」:即使每次抵消一对不同元素,最终剩下的元素一定是绝对众数(如果存在的话)。
举个例子:数组 [2,2,1,1,1,2,2],绝对众数是 2(出现 5 次,超过 7/2=3.5)。遍历过程中,2 和 1 不断抵消,但 2 的数量更多,最终会成为候选值。
三、算法执行步骤 固定流程
以求解「数组中出现次数超过 n/2 的元素」为例,步骤标准化,无任何变种:
- 初始化:
candidate = None,count = 0; - 第一次遍历(抵消阶段):
- 遍历数组中的每个元素
num; - 若
count == 0,令candidate = num; - 若
num == candidate,count += 1,否则count -= 1;
- 遍历数组中的每个元素
- 第二次遍历(验证阶段):
- 统计
candidate在数组中的出现次数total; - 若
total > n/2,返回candidate,否则返回None(无绝对众数)。
- 统计
四、完整实现代码 两种版本
版本 1 基础版(含验证阶段,推荐)
def majority_element():
candidate =
count =
num nums:
count == :
candidate = num
count += num == candidate -
total =
num nums:
num == candidate:
total +=
candidate total > (nums) //


