基于豆包MarsCode AI的摩尔投票算法学习笔记:题目链接
摩尔投票算法(Moore Voting Algorithm)是一种用于寻找数组中多数元素的算法。多数元素是指在数组中出现次数超过一半的元素。摩尔算法因其简单且高效的特性而被广泛用于数据处理场景中。
核心思路
摩尔投票算法的核心思想是“抵消”原则。将数组中的每个元素视为一个选票,通过相互抵消的方式,最终留下的元素即为数组中的多数元素(如果存在)。这种思路利用了多数元素出现次数超过总数一半的特性,确保最终留下的元素一定是多数元素。
算法分为两个步骤:
- 候选人阶段:通过一次遍历找到一个“可能的候选多数元素”。
- 验证阶段:再次遍历数组,验证候选元素是否为多数元素。
候选人阶段
- 初始时,没有候选人,计票值(
count)为 0。 - 遍历数组:
- 如果
count为 0,选择当前元素作为候选人,将count设为 1。 - 如果当前元素等于候选人,
count增加 1。 - 如果当前元素不等于候选人,
count减少 1。
- 如果
这一阶段的作用是利用抵消的方式过滤掉非多数元素。
验证阶段
由于候选人阶段仅保证了候选人是可能的多数元素,需再次遍历数组以确认该候选人是否确实为多数元素(即,出现次数是否超过一半)。
示例摩尔算法
以下是一个示例数组:[3, 3, 4, 2, 4, 4, 2, 4, 4]。目标是找到多数元素。
1、候选人阶段:
- 第一个元素为 3,设为候选人,
count = 1。 - 第二个元素为 3,与候选人相同,
count = 2。 - 第三个元素为 4,与候选人不同,
count = 1。 - 第四个元素为 2,与候选人不同,
count = 0。 - 第五个元素为 4,
count = 1,候选人更改为 4。 - 持续更新后,候选人为 4,
count = 3。
2、验证阶段:
- 统计 4 的出现次数,共出现 5 次,占数组长度的一半以上。因此,多数元素为 4。
代码实现
int solution(vector<int> array) {
// 摩尔投票算法
int candidate = 0;
int cnt = 0;
for (auto a : array) {
if (cnt == 0) {
candidate = a;
cnt = 1;
} else if (candidate == a) {
cnt++;
} else if (candidate != a) {
cnt--;
}
}
return candidate;
}
个人理解
摩尔算法的巧妙之处在于“抵消”思想,避免了传统方法需要频繁计数的高开销操作。相比于直接统计每个元素出现次数,摩尔算法的时间复杂度为 O(n),且只需常数级空间,非常高效。
- 时间复杂度:线性遍历,总时间复杂度为 O(n)。
- 空间复杂度:常数级 O(1),仅使用少量变量。
在理解算法时,最关键的一点是认识到候选人阶段的过滤效果:只要存在多数元素,其在抵消后必然会“存活”。