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

发布时间:2026/11/5 16:44:26

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/11/5 3:45:40

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

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

2026/10/23 23:44:37

基于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/11/5 16:26:13

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

2026/11/5 15:00:49

基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享…

2026/11/5 14:10:30

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

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

2026/11/5 14:10:30

UART接口24位ADC搭配RS485,解决远距离温度监控难题

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

2026/11/5 14:10:30

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

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

2026/11/5 13:55:19

GD32E10x官方例程入门:从GPIO点灯到串口调试

简介:这份GD32E10x系列官方例程面向嵌入式硬件与单片机开发者,基于ARM Cortex-M3内核,汇集兆易创新GD32E10x的示例代码,适合工业控制、消费电子、通信设备等场景的学习、验证与二次开发。压缩包共935个文件,约11.16MB&…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

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

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

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

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