LeetCode-Go 题解:229. Majority Element II —— Boyer-Moore 多数投票算法求出现次数超过 n/3 的元素

发布时间:2026/9/10 1:26:05

LeetCode-Go 题解:229. Majority Element II —— Boyer-Moore 多数投票算法求出现次数超过 n/3 的元素 LeetCode-Go 题解229. Majority Element II —— Boyer-Moore 多数投票算法求出现次数超过 n/3 的元素【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go导读本篇文章围绕 LeetCode 第 229 题 Majority Element II求数组中出现次数超过 ⌊n/3⌋ 的所有元素展开以 0229 题解文档 为核心骨架并结合仓库中 229 题 Go 实现 与 单元测试 进行源码级佐证。读完本文你将掌握为什么超过 ⌊n/3⌋ 的元素至多只有两个、如何把经典的 Boyer-Moore 多数投票算法从“找 1 个众数”扩展为“找 2 个候选者”以及如何在 O(n) 时间、O(1) 空间内一次性筛出全部答案。题目描述Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times.Note: The algorithm should run in linear time and in O(1) space.题目大意给定一个大小为 n 的整数数组找出其中所有出现次数超过 ⌊ n/3 ⌋ 次的元素。算法要求时间复杂度为 O(n)空间复杂度为 O(1)。示例 1Input: [3,2,3] Output: [3]示例 2Input: [1,1,1,3,3,2,2,2] Output: [1,2]解题思路与 169 题的关系从“1 个众数”到“2 个候选者”本题是 169. Majority Element找出现次数大于 ⌊n/2⌋ 的众数的加强版采用的算法是Boyer-Moore Majority Vote Algorithm摩尔投票算法的扩展版。先回顾 169 题的核心思想数组中超过一半的元素可以与所有其他元素“一对一抵消”后仍然存活。因此维护一个候选者和一个计数器遍历数组时计数为 0 就换候选人相同则 1、不同则 -1最终剩下的候选者即为众数。仓库中 169 题的 解法一实现 正是这一思想的直接体现// 解法一 时间复杂度 O(n) 空间复杂度 O(1) func majorityElement(nums []int) int { res, count : nums[0], 0 for i : 0; i len(nums); i { if count 0 { res, count nums[i], 1 } else { if nums[i] res { count } else { count-- } } } return res }而 229 题把阈值从 ⌊n/2⌋ 降到 ⌊n/3⌋问题结构发生了质变超过 ⌊n/2⌋ 的元素至多存在 1 个所以 169 题只需维护 1 个候选者超过 ⌊n/3⌋ 的元素至多存在 2 个——因为若有 3 个元素都超过 n/3它们出现次数之和将大于 n与总和为 n 矛盾。源码注释精确地表达了这一推导// since we are checking if a num appears more than 1/3 of the time // it is only possible to have at most 2 nums (1/3 1/3 2/3)因此算法需要同时维护两个候选者 candidate1、candidate2 和两个计数器 count1、count2这就是 Boyer-Moore 投票算法的扩展形式。扩展投票双候选者的三阶段流程仓库中 229. Majority Element II.go 的解法一完整实现了该算法整个流程分为三个阶段阶段一选举候选者Select Candidates遍历数组对每个元素 num 依次判断若num candidate1则count1否则若num candidate2则count2否则若count1 0说明候选者 1 已“弹尽粮绝”把candidate1替换为 num重置count1 1否则若count2 0同理替换候选者 2否则两个候选者“双双失血”count1--、count2--。这一阶段结束后真正超过 ⌊n/3⌋ 的元素一定留在两个候选者之中因为它的出现次数足以抵消所有其他元素而不被替换掉但候选者并不一定是答案——由于计数可能被互相抵消可能出现“没有候选者真正超过 ⌊n/3⌋”的情况例如数组[1,2,3,4]。阶段二重新计数Recount将count1、count2清零再次遍历数组分别统计candidate1与candidate2的真实出现次数。这一步是扩展版与 169 题的关键差异169 题可假定众数必然存在而本题不能必须用真实计数做最终裁决。阶段三按阈值过滤输出length : len(nums) if count1 length/3 count2 length/3 { return []int{candidate1, candidate2} } if count1 length/3 { return []int{candidate1} } if count2 length/3 { return []int{candidate2} } return []int{}分别判断两个候选者的计数是否严格大于length/3按情况返回两个、一个或空切片。注意必须严格大于恰好等于 ⌊n/3⌋ 不算答案。初始值的一个易错细节实现中初始化为count1, count2, candidate1, candidate2 : 0, 0, 0, 1即两个候选者初始值不同0 与 1。原因在于若两个候选者初始值相同当数组第一个元素恰好等于该值时两个分支会同时命中导致计数混乱。由于题目并未限定元素取值范围采用两个不同的占位初值可以规避这一边界问题也无需依赖 nil/哨兵值。复杂度分析时间复杂度O(n)。两次线性扫描选举 重新计数每次都是单层循环无嵌套。空间复杂度O(1)。只使用 4 个固定整型变量两个候选者 两个计数器不随输入规模增长。完全满足题目要求的 linear time 与 O(1) space。另一种解法哈希表计数O(n) 空间如果题目没有 O(1) 空间约束解法二 提供了更直观的哈希表方案第一遍遍历用map[int]int统计每个元素出现次数第二遍遍历 map把计数大于len(nums)/3的键收集进结果切片// 解法二 时间复杂度 O(n) 空间复杂度 O(n) func majorityElement229_1(nums []int) []int { result, m : make([]int, 0), make(map[int]int) for _, val : range nums { if v, ok : m[val]; ok { m[val] v 1 } else { m[val] 1 } } for k, v : range m { if v len(nums)/3 { result append(result, k) } } return result }该写法在 169 题中同样有对应的 map 计数版实现。它时间上仍为 O(n)但空间升为 O(n)可作为理解题意与验证投票算法正确性的参照实现。单元测试验证仓库为该题提供了 229. Majority Element II_test.go覆盖了 4 组典型用例恰好对应上述所有边界分支输入预期输出覆盖场景[3,2,3][3]恰好 1 个元素超过 n/32/3 次[1,1,1,3,3,2,2,2][1,2]同时存在 2 个元素超过 n/3[1,2,3,4][]没有任何元素超过 n/3返回空切片[2,1,1,1,3][1]1 出现 3 次 5/3其余均不满足测试驱动方式为表驱动测试table-driven定义question229结构体组合输入para229与期望答案ans229遍历用例后同时调用majorityElement229与majorityElement229_1两种实现确保两套解法行为一致。其中[1,2,3,4]这一用例特别有价值——它专门验证了“候选者不一定为答案”的边界投票阶段会留下两个候选者但重新计数后发现二者都不达标最终正确返回空切片。小结超过 ⌊n/3⌋ 的元素至多两个这是算法可行性的数学前提Boyer-Moore 投票算法扩展版通过维护双候选者 双计数器在一次线性遍历中完成“候选人筛选”再用第二次线性遍历做“真实计票”最终在 O(n) 时间、O(1) 空间内找出全部答案与 169 题的关键区别在于169 题众数必然存在可直接返回候选者而本题必须重新计数验证因为候选者可能“虚高”仓库提供了投票版与哈希表版两套实现并由覆盖 4 种边界情形的表驱动测试保证正确性可直接参考 实现源码 与 测试源码 深入研读。【免费下载链接】LeetCode-Go✅ Solutions to LeetCode by Go, 100% test coverage, runtime beats 100% | LeetCode 题解项目地址: https://gitcode.com/GitHub_Trending/le/LeetCode-Go创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/10 1:26:05

基于SpringBoot的文旅信息服务平台核心实现与常见踩坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/10 1:21:05

基于Django+Vue3的校园租房系统全栈开发实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/10 2:26:13

AI率过高如何解决?2026年10款主流降AI率工具终极亲测指南

现在毕业生答辩前的头号难关,早就从“查重率超标”变成“AIGC率踩红线”啦!各大高校检测系统一升级,AI痕迹太明显被标红,那可是答辩路上的“致命关卡”,半点儿都马虎不得。 为啥自己改来改去还是过不了?因…

2026/9/10 2:26:13

SEO总监的真实工作:管理、协作与数据驱动的实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/10 2:21:13

Java面试必问:new String(“abc“)到底创建了几个对象?

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/9 13:11:35

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/8 7:15:15

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/9 16:31:09

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/10 0:00:55

目录对比去重实战:用哈希算法精准清理重复文件

我电脑里现在还有一块换了三次机的“数据墓地”硬盘,里面存着2016年以前所有旧笔记本的完整备份。平时不觉得有什么,直到前阵子想把它整理归档,发现同一个安装包、同一批照片、同一份论文草稿,在几个不同的备份目录里反复出现。更…

2026/9/10 0:00:55

Leaflet离线地图完整Demo合集:内网部署与坐标纠偏实战

简介:这是一份面向Web GIS开发者的LeafLet离线地图示例合集,帮助开发者快速掌握离线地图从搭建到交互的完整流程。压缩包共723个文件,大小14.06MB,以319个js脚本、175个html页面和29个css样式文件为主体,配合png/svg图…

2026/9/10 0:00:55

MATLAB读取Rinex 3.02观测文件:多系统GNSS数据解析实战

简介:基于MATLAB开发的Rinex3.02版观测文件(o文件)读取代码包,面向卫星定位导航方向的学习者与研究人员,用于解决新版观测文件的数据解析、历元提取与时间转换问题。压缩包共4个文件,包含两个m脚本、一个19…

2026/9/7 16:23:03

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/7 22:46:00

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/9 10:21:54

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码