尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

摩尔投票法

摩尔投票法
📅 发布时间:2026/6/19 4:16:10

0、参考资料(讲解视频及博客等)

  • 本人水平有限,如有错误,恳请指正
  • 讲解视频:【【算法】摩尔投票法】

一、应用场景

  • 典型应用场景:在一个数组中,寻找出现次数超过总元素数一半的元素(即 “主元素”);也可扩展到寻找出现次数超过 kn​ 的元素(需结合多候选抵消逻辑)。
  • 场景特点:数组规模大,要求时间复杂度尽可能低(线性时间)、空间复杂度尽可能小(常数空间),避免额外存储大量计数信息。

二、核心思想 / 步骤

摩尔投票法的核心是 “计数抵消”:利用 “多数元素的数量优势”,让不同元素相互抵消,最终筛选出候选元素,再通过验证确认是否为目标。
分为两个核心阶段:

  1. 候选元素筛选:
    • 初始化:选数组第一个元素为候选元素,计数 count = 1(表示候选的 “剩余优势次数”)。
    • 遍历数组后续元素:
      • 若当前元素与候选元素相同:count++(强化候选的 “数量优势”)。
      • 若当前元素与候选元素不同:
        • 若 count > 0:count--(用候选的 “优势次数” 抵消当前不同元素)。
        • 若 count == 0:更换候选元素为当前元素,重置 count = 1(原候选已被完全抵消,新候选重新积累优势)。
  2. 候选元素验证:
    • 遍历结束后,候选元素是 “可能的多数元素”,但需再次遍历数组,统计其实际出现次数。
    • 若实际次数超过总元素数的一半,则确认为主元素;否则说明不存在主元素(避免抵消过程中的误判)。

三、代码模板与测试

代码模板 (C 语言为例)

int majorityElement(int* nums, int numsSize) {int candidate = nums[0]; // 初始化候选元素int count = 1;           // 候选元素的计数// 阶段1:筛选候选元素for (int i = 1; i < numsSize; i++) {if (nums[i] == candidate) {//为候选人得票count++;} else {//竞争对手if (count > 0) {count--;//冲突抵消} else {//cnt = 0,更换候选人candidate = nums[i];count = 1;}}}// 阶段2:验证候选元素(若题目确保存在主元素,可省略此阶段)int verifyCount = 0;for (int i = 0; i < numsSize; i++) {if (nums[i] == candidate) {verifyCount++;}}return (verifyCount > numsSize / 2) ? candidate : -1; // 存在返回候选,否则返回-1
}

样例

寻找数组中的主元素(出现次数超过一半的元素)
输入:nums = {0, 5, 5, 3, 5, 7, 5, 5}(长度为 8,5 出现 5 次,超过 8/2=4 次)
输出:5

#include <stdio.h>int majorityElement(int* nums, int numsSize) {int candidate = nums[0];int count = 1;for (int i = 1; i < numsSize; i++) {if (nums[i] == candidate) count++;else {if (count > 0) count--;else {candidate = nums[i];count = 1;}}}int verify = 0;for (int i = 0; i < numsSize; i++) if (nums[i] == candidate) verify++;return verify > numsSize / 2 ? candidate : -1;
}int main() {int nums[] = {0, 5, 5, 3, 5, 7, 5, 5};int size = sizeof(nums) / sizeof(nums[0]);int result = majorityElement(nums, size);printf("主元素:%d\n", result); // 输出:5return 0;
}

四、优化与同类算法对比

优化方案

  • 若题目明确保证存在主元素(如 LeetCode 169 题),可直接省略 “验证阶段”,遍历一次即可返回候选元素,此时时间复杂度为 O(n),空间复杂度为 O(1)(最优)。
  • 扩展场景(找出现次数超过 kn​ 的元素):需维护 k−1 个候选及对应计数,逻辑类似 “多候选相互抵消”,最终再验证每个候选的实际次数。

算法对比 / 复杂度分析

算法 时间复杂度 空间复杂度 适用场景 优缺点
摩尔投票法 O(n) O(1) 找 “超半数” 或 “超 kn​” 元素 时间、空间最优;但仅适用于 “数量优势类” 问题,通用性弱。
哈希表计数 O(n) O(n) 任意频率统计 通用但空间开销大,哈希表存储所有元素的计数。
排序后取中间 O(nlogn) O(1)(原地排序) 仅适用于 “超半数” 场景(排序后中间元素必为目标) 时间开销高(排序),但无需额外验证。

五、相关 LeetCode 题目推荐

  • LeetCode 169. 多数元素(基础应用,保证存在主元素)
  • LeetCode 229. 多数元素 II(扩展应用,找出现次数超过 3n​ 的元素)
  • LeetCode 面试题 17.10. 主要元素(需验证主元素是否存在)
  • 408统考2013年真题

相关新闻

  • 基于STM32平台的ADS1292心电采集驱动程序
  • C#开发的等待界面类库例子 - 开源研究系列文章
  • 邀您参加丨云栖大会中企出海技术分论坛

最新新闻

  • C#StreamWriter 与 File.AppendAllText 写入文本核心区别
  • 普宁哪家家具质量好|质保久用料扎实哪家店 - 品牌观察
  • 懂游宝(懂淘app)新品牌逆势增长,276家品牌年销破亿
  • 第1周学习总结
  • go:Producer Consumer Pattern
  • 高温冶炼车间炉前工位工业平板采购方案,避开高温死机故障

日新闻

  • 5分钟掌握Python进化算法:Geatpy高性能优化工具完全指南
  • Microchip 24AA044 EEPROM选型与应用全指南:从参数解析到实战编程
  • 华为的鸿蒙到底有多牛?为什么称作遥遥领先?

周新闻

  • 3步解锁iOS设备:applera1n激活锁绕过完全指南
  • 39 2026 人工智能证书终极盘点,普通人选 AI 证书可以从这些方向入手
  • Redis 暴露公网有多危险?从端口检查到补救步骤

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号