当前位置: 首页 > article >正文

[特殊字符] 数组中的多数元素 II:Boyer-Moore投票算法详解

问题描述给定一个包含 n 个整数的数组 arr[]找出所有出现次数超过 floor(n/3) 次的数组元素。注意返回的多数元素数组应该是排序的。示例输入arr[] [2, 2, 3, 1, 3, 2, 1, 1]输出[1, 2]解释1 和 2 的频率都是 3大于 floor(8/3) 2。输入arr[] [-5, 3, -5]输出[-5]解释-5 的频率是 2大于 floor(3/3) 1。输入arr[] [3, 2, 2, 4, 1, 4]输出[ ]解释没有多数元素。目录朴素方法使用嵌套循环 - O(n²) 时间 O(1) 空间期望方法Boyer-Moore投票算法 - O(n) 时间 O(1) 空间说实话啃这种算法题光看文字推导确实容易绕晕。最近发现一个叫图码的网站把Boyer-Moore这种算法的执行过程做成了交互式动画每一步怎么投票、怎么抵消拖一下进度条就全明白了。它不仅有60多种算法的可视化演示还支持你把自定义的测试数据或者自己写的C/Python代码直接丢进去自动生成动画解析。对于准备408考研和数据结构期末考试的同学这简直是复习利器。强烈建议去体验一下比干看代码效率高太多了。图码-数据结构与算法交互式可视化平台访问网站https://totuma.cn朴素方法使用嵌套循环 - O(n²) 时间 O(1) 空间思路遍历所有元素统计每个元素在数组中的频率。如果某个元素的频率大于 floor(n/3)则将其添加到结果中。为了避免在结果中添加重复元素可以检查该元素是否已经存在于结果中。如果已经找到了两个多数元素就可以停止搜索。代码实现简化版deffindMajority(arr):nlen(arr)res[]foriinrange(n):# 统计 arr[i] 的频率cnt0forjinrange(i,n):ifarr[j]arr[i]:cnt1# 检查 arr[i] 是否是多数元素ifcnt(n//3):# 如果结果中还没有该元素则添加iflen(res)0orarr[i]!res[0]:res.append(arr[i])# 如果已经找到两个多数元素停止搜索iflen(res)2:ifres[0]res[1]:res[0],res[1]res[1],res[0]breakreturnresif__name____main__:arr[2,2,3,1,3,2,1,1]resfindMajority(arr)foreleinres:print(ele,end )输出1 2注意我们也可以通过排序然后进行一次遍历来解决这个问题时间复杂度为 O(n log n)。另一种方法是使用哈希表统计频率可以在线性时间内解决但需要 O(n) 的额外空间。下面的方法可以在线性时间和常数额外空间内解决。期望方法Boyer-Moore投票算法 - O(n) 时间 O(1) 空间思路基于这样一个观察最多只能有两个多数元素它们出现的次数超过 n/3 次。当我们遍历数组时通过跟踪两个候选元素及其各自的计数来识别潜在的多数元素。步骤初始化两个候选变量 ele1 -1 和 ele2 -1以及两个计数变量 cnt1 0 和 cnt2 0。在每次迭代中如果当前元素等于某个候选元素则更新该候选元素的计数。如果某个候选元素的计数变为零则用当前元素替换该候选元素。如果当前元素既不匹配任何候选元素且两个计数都非零则两个计数都减 1。在第二轮遍历中检查选出的候选元素是否在数组中出现超过 n/3 次。如果是则将其包含在结果数组中。为什么有效任何出现次数超过 floor(n/3) 次的元素都会比出现频率较低的元素占据优势。每当我们遇到一个不同的元素我们就减少两个候选元素的计数。这保证了数组中最多只有两个候选元素。代码实现简化版deffindMajority(arr):nlen(arr)# 初始化两个候选元素及其计数ele1,ele2-1,-1cnt1,cnt20,0foreleinarr:# 增加候选元素 1 的计数ifele1ele:cnt11# 增加候选元素 2 的计数elifele2ele:cnt21# 如果候选元素 1 的计数为零设置新候选elifcnt10:ele1ele cnt11# 如果候选元素 2 的计数为零设置新候选elifcnt20:ele2ele cnt21# 如果都不匹配两个计数都减 1else:cnt1-1cnt2-1res[]cnt1,cnt20,0# 统计候选元素出现的次数foreleinarr:ifele1ele:cnt11ifele2ele:cnt21# 如果是多数元素则添加到结果中ifcnt1n/3:res.append(ele1)ifcnt2n/3andele1!ele2:res.append(ele2)iflen(res)2andres[0]res[1]:res[0],res[1]res[1],res[0]returnresif__name____main__:arr[2,2,3,1,3,2,1,1]resfindMajority(arr)foreleinres:print(ele,end )输出1 2复杂度分析方法时间复杂度空间复杂度朴素方法嵌套循环O(n²)O(1)排序方法O(n log n)O(1)哈希表方法O(n)O(n)Boyer-Moore投票算法O(n)O(1)Boyer-Moore投票算法是解决这类问题的最优方案它在线性时间内完成并且只使用常数级别的额外空间非常适合处理大规模数据。

相关文章:

[特殊字符] 数组中的多数元素 II:Boyer-Moore投票算法详解

问题描述 给定一个包含 n 个整数的数组 arr[],找出所有出现次数超过 floor(n/3) 次的数组元素。 注意:返回的多数元素数组应该是排序的。 示例: 输入:arr[] [2, 2, 3, 1, 3, 2, 1, 1] 输出:[1, 2] 解释&#xff1a…...

开源情报实战指南:从工具到体系的OSINT方法论与自动化实践

1. 项目概述:一个开源情报收集的实战指南最近在整理自己的安全工具箱时,发现很多朋友对开源情报(OSINT)的实战应用很感兴趣,但往往止步于理论,或者被海量的工具和碎片化的信息淹没。恰好,我在Gi…...

微信福音:2345清理王微信专清功能介绍

现在大家用微信的时间越来越长,微信里的缓存也越攒越多,经常是好几个G,特别占空间。但是想清理又怕删错重要数据,不敢随便动手。这时候,微信专清功能就显得尤为重要。2345清理王的微信专清功能,完美解决了这…...

Termi AI:基于Electron的智能桌面开发伴侣,集成Vite预览与AI编程助手

1. 项目概述:一个集成了AI助手的桌面开发伴侣如果你和我一样,每天大部分时间都泡在终端和编辑器里,那你肯定也幻想过:能不能有一个工具,能把我的项目实时预览和AI编程助手无缝地“焊”在一起?不用在浏览器、…...

AI编程助手集成Codex CLI:MCP协议实现智能代码分析与本地模型部署

1. 项目概述:连接AI与代码的智能桥梁 如果你和我一样,日常开发中频繁使用 Claude 或 Cursor 这类AI编程助手,同时又深度依赖 OpenAI Codex CLI 进行代码分析和重构,那么你很可能面临一个效率瓶颈:如何在不同的工具之间…...

【EAI(企业应用集成)工具】Asteria warp簡単紹介(アステリア ワープ)

目录 ■前言 ■Asteria warp簡単紹介 ■ASTERIA Warpとは ■ASTERIA Warp 命名哲学 ■ASTERIA WARPについて ■19年連続国内シェアNo.1 ■10,000社以上の企業での導入実績 ■ノーコードだから誰でも使える ■市场地位:日本市场的绝对王者 ■核心产品力&am…...

BrowserGym:基于LLM的浏览器自动化智能体开发实战指南

1. 项目概述:当浏览器自动化遇上大语言模型最近在探索大语言模型(LLM)与真实世界应用交互的边界时,我深度体验了ServiceNow开源的BrowserGym项目。这不仅仅是一个简单的网页自动化工具,它更像是一个为LLM量身定制的“浏…...

【收藏级】2026年大模型入门指南:小白程序员必看,告别AI焦虑,轻松切入AI行业

这篇文章想聊清楚一个很现实的问题:在2026年AI热潮愈演愈烈的今天,小白和程序员到底该怎么低成本进入AI行业? 如果你最近也在焦虑、在内耗,刷到各种AI热点就心慌,不知道该学什么、不知道该怎么开始,甚至担心…...

构建本地优先的代码片段管理工具:从设计到实践

1. 项目概述:一个为开发者量身定制的代码片段管理工具如果你和我一样,是个每天和代码打交道的开发者,那你肯定遇到过这样的场景:为了解决一个特定的问题,你花了半天时间在网上搜索、调试,终于写出了一段堪称…...

Flutter for OpenHarmony 中 webview_flutter 适配实战指南

Flutter for OpenHarmony 中 webview_flutter 适配实战指南 欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net 摘要 本文基于真实项目实践,完整介绍了在 Flutter for OpenHarmony(以下简称 FOH)工程中&…...

LangGraph 终极解析:从 “玩具 Agent“ 到 “生产级智能体“ 的核心武器

目录 LangGraph 终极解析:从 "玩具 Agent" 到 "生产级智能体" 的核心武器 一句话定位 为什么必须学 LangGraph?(LangChain 的致命缺陷) LangGraph 四大核心概念(一张图搞懂) 1. S…...

python系列【仅供参考】:js2py模块--python中执行js

js2py模块--python中执行js js2py 1. 在python中执行js代码 2. js代码翻译 3. 在js中调用Python函数 4. 在js中调用Python模块 js2py Python中执行JS代码,通常用两个库:js2py,pyexecjs。当网页使用 js 加密时我们可以使用这些库来分析 js 的实现逻辑,获取加密信息。 js2p…...

下载安装 Temurin® JDK JDK 21 - LTS 速度很慢,有办法加速吗?

下载 Temurin JDK JDK 21 - LTS 速度很慢,有办法加速吗? 加速下载 Temurin JDK 21 的方法 方法一:清华大学 TUNA 镜像(推荐 ⭐⭐⭐⭐⭐) 这是目前最快、最稳定的国内镜像,速度可以跑满带宽。 直接访问目…...

Godot XR Tools:加速VR/AR开发的模块化工具集与实战指南

1. 项目概述:Godot XR Tools 是什么? 如果你正在用 Godot 引擎捣鼓 VR 或 AR 项目,大概率会遇到一些“通用但繁琐”的问题:怎么让虚拟手自然地抓取物体?怎么实现一个稳定可靠的传送移动机制?UI 界面在 3D …...

python系列【仅供参考】:JS的解析与Js2Py使用

JS的解析与Js2Py使用 JS的解析与Js2Py使用 简介: JS的解析 事件监听器 搜索关键字 请求关联JS文件 Js2Py Js2Py的简单使用 安装Js2Py 执行JavaScript代码 调用JavaScript函数 Js2Py的应用示例 创建JavaScript文件 使用JavaScript JS的解析与Js2Py使用 简介: Js2Py是一个Pyt…...

基于工作流的低代码AI应用开发:Flock平台核心架构与实战指南

1. 项目概述:Flock,一个为AI应用构建者准备的“乐高积木”如果你正在寻找一个工具,能够让你像搭积木一样,快速构建出功能强大的聊天机器人、智能客服,甚至是能自主协作的多智能体系统,那么Flock很可能就是你…...

深入Android Framework:构建稳定、高效的无人售卖机系统

摘要: 本文聚焦于Android Framework框架层,探讨其在无人售卖机系统开发中的核心价值与应用实践。区别于常规应用层开发,无人售卖机因其特殊的运行环境(如弱网、断电风险、多外设交互)及业务需求(如交易安全、设备状态监控、离线能力),对Android系统的底层能力提出了更高…...

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南

如何在华为HarmonyOS设备上部署microG服务:解决签名验证的完整技术指南 【免费下载链接】GmsCore Free implementation of Play Services 项目地址: https://gitcode.com/GitHub_Trending/gm/GmsCore microG Services是一个开源免费的Google Play服务替代框架…...

#81_闲谈语言的分类

机器语言是二进制指令,CPU可直接执行; 低级语言通常指机器语言和汇编语言,与硬件紧密相关; 高级语言则接近自然语言,独立于具体硬件,需编译/解释才能运行; 中级语言并非严格分类,有时…...

golang如何实现桌面应用热更新_golang桌面应用热更新实现攻略

Go桌面应用无法真正热更新,只能通过go-selfupdate实现无缝重启:下载校验新二进制、替换并重启,需适配各平台签名与自启机制,插件机制不可行,核心难点在于更新时机判断与状态快照恢复。Go 桌面应用热更新无法真正“热”…...

5分钟快速上手!Calibre豆瓣插件终极安装指南,轻松获取中文图书元数据

5分钟快速上手!Calibre豆瓣插件终极安装指南,轻松获取中文图书元数据 【免费下载链接】calibre-douban Calibre new douban metadata source plugin. Douban no longer provides book APIs to the public, so it can only use web crawling to obtain da…...

为什么很多人 DFS 写得飞起,一到「矩阵最长递增路径」就彻底懵了?

为什么很多人 DFS 写得飞起,一到「矩阵最长递增路径」就彻底懵了? 有一类算法题,非常容易让人产生错觉。 看起来只是: 矩阵 + DFS结果一写。 不是超时。 就是死循环。 再不然: 明明逻辑没错 结果性能直接爆炸而「矩阵中的最长递增路径(Longest Increasing Path in a…...

欧拉回路(一笔画)

欧拉回路是图论中的一个经典概念,指一条经过图中每条边恰好一次并且起点和终点相同的闭合路径。通俗地讲,就是一笔画问题中能够不重复地走完所有边并回到起点的画法。 基本定义 欧拉回路:经过图中每条边恰好一次且闭合的回路。 欧拉通路&am…...

吃透C++ STL map/set:从入门到实战,新手也能轻松上手

文章目录 前言 一、先搞懂:map和set是什么?核心区别在哪? 二、set使用详解:去重排序,一键搞定 三、map使用详解:键值映射,高效查找 四、map和set的常见避坑点(新手必看&#xff…...

Dify插件开发实战:Python SDK快速构建AI工作流扩展工具

1. 项目概述与核心价值如果你正在为 Dify 构建自定义插件,并且厌倦了从零开始处理复杂的协议、序列化和生命周期管理,那么langgenius/dify-plugin-sdks这个项目就是你一直在找的“脚手架”。简单来说,它是一套官方维护的软件开发工具包&#…...

私有化部署ChatGPT Web应用:从架构解析到实战部署指南

1. 项目概述与核心价值最近在折腾一个挺有意思的开源项目,叫“ChatGPTwebV15”。这名字听起来有点技术范儿,但说白了,就是一个让你能自己部署、完全掌控的类ChatGPT网页应用。它基于OpenAI的API,但把整个交互界面、对话管理、甚至…...

如何在手机上3步完成Android内核刷入:Horizon Kernel Flasher终极指南

如何在手机上3步完成Android内核刷入:Horizon Kernel Flasher终极指南 【免费下载链接】HorizonKernelFlasher A simple app that can flash AnyKernel flashable zips on android 项目地址: https://gitcode.com/gh_mirrors/ho/HorizonKernelFlasher 还在为…...

2026.5.7@霖宇博客制作中遇见的问题

倒数2个知识点没看 记得看下1. one 前端网页的验证码如何修改为后端的验证码 将前端生成的验证码修改为后端生成,核心目的是为了解决安全性问题。如果验证码只在前端生成和校验,恶意攻击者可以轻松绕过登录页面直接发起请求,导致验证码完全失…...

国家医疗保障webpack

开始逆向 定位到signature的位置 发现是webpack模块 要找到入口位置 这一块是加载器的位置 先把这个扣下来 再扣自执行函数 不要里面的函数 会报环境错误 然后报这个错误 把加载器函数调用注释 o函数挂载到全局去调用 代码全拉 然后注释掉 这一块是 类ob 然后报t is not define…...

C语言实现精简Smalltalk运行时:探索面向对象与消息传递的本质

1. 项目概述:当“小结构”遇上“小对话”如果你在开源社区里混迹过一段时间,可能会发现一个有趣的现象:很多项目的名字,乍一看不知所云,但一旦你理解了它的设计哲学,就会觉得无比贴切。tinystruct/smalltal…...