扩展摩尔投票法:找出出现次数超过 n/3 的元素

文章目录

    • 问题描述
    • 关键洞察
    • 算法原理
    • Java 实现
    • 算法演示
      • 投票阶段
      • 验证阶段
    • 复杂度分析
    • 算法关键点
    • 通用化公式
    • 实际应用场景
    • 边界情况处理
    • 总结

标签:LeetCode 169, 摩尔投票法, 多数元素, 算法扩展, 数组处理

在解决多数元素问题时,我们学习了经典的摩尔投票法处理出现次数超过 n/2 的情况。那么,当问题扩展为找出出现次数超过 n/3 的元素时,该如何解决呢?本文将深入探讨摩尔投票法的扩展应用。

问题描述

给定一个大小为 n 的整数数组,找出所有出现次数 大于 ⌊n/3⌋ 的元素。要求时间复杂度 O(n),空间复杂度 O(1)。

示例:

输入:[1,1,1,3,3,2,2,2]
输出:[1,2]
解释:1 和 2 都出现 3 次,大于 ⌊8/3⌋ = 2

关键洞察

  1. 数学约束:出现次数超过 n/3 的元素最多有 2 个

    • 如果 3 个元素都超过 n/3,总次数将超过 n,不可能
  2. 扩展思路:使用两个候选元素和两个计数器

    • 维护两个候选元素 candidate1, candidate2
    • 维护对应的计数器 count1, count2
    • 使用抵消策略处理其他元素

算法原理

  1. 初始化:两个候选元素设为特殊值(如 null),计数器设为 0
  2. 投票阶段
    • 当前元素等于任一候选元素 → 对应计数器加 1
    • 当任一计数器为 0 → 将当前元素设为新候选
    • 当前元素不等于任一候选 → 两个计数器都减 1(抵消)
  3. 验证阶段:检查候选元素是否真正超过 n/3

Java 实现

import java.util.*;class Solution {public List<Integer> majorityElement(int[] nums) {// 初始化候选元素和计数器Integer candidate1 = null;Integer candidate2 = null;int count1 = 0;int count2 = 0;// 第一轮遍历:投票过程for (int num : nums) {if (candidate1 != null && num == candidate1) {count1++;} else if (candidate2 != null && num == candidate2) {count2++;} else if (count1 == 0) {candidate1 = num;count1 = 1;} else if (count2 == 0) {candidate2 = num;count2 = 1;} else {// 抵消操作count1--;count2--;}}// 第二轮遍历:验证候选元素List<Integer> result = new ArrayList<>();count1 = 0;count2 = 0;for (int num : nums) {if (candidate1 != null && num == candidate1) count1++;if (candidate2 != null && num == candidate2) count2++;}int n = nums.length;if (count1 > n/3) result.add(candidate1);if (count2 > n/3) result.add(candidate2);return result;}
}

算法演示

以数组 [1,2,3,2,1,2,3,1,2] 为例(n=9,需要出现次数 > 3)

投票阶段

元素candidate1count1candidate2count2操作说明
111null0初始化 candidate1
21121初始化 candidate2
31020抵消 (1-1, 2-1)
21021count1=0, 使用candidate2
11121重置 candidate1
21122增加 candidate2
31021抵消
11121重置 candidate1
21122增加 candidate2

验证阶段

  • candidate1 = 1 → 出现次数:4 > 3
  • candidate2 = 2 → 出现次数:4 > 3
  • 结果:[1, 2]

复杂度分析

  • 时间复杂度:O(2n) = O(n),两次线性遍历
  • 空间复杂度:O(1),仅使用常数空间(两个候选元素和两个计数器)

算法关键点

  1. 候选元素初始化:使用包装类型 Integer 以便处理 null 值
  2. 条件判断顺序:优先检查是否匹配候选元素,再检查计数器是否为0
  3. 抵消策略:当元素与两个候选元素都不同时,同时减少两个计数器
  4. 验证必要性:投票结果需要验证,因为:
    • 计数器可能被其他元素干扰
    • 数组可能没有满足条件的元素

通用化公式

摩尔投票法可进一步扩展为寻找出现次数超过 n/k 的元素:

  1. 最多有 k-1 个候选元素
  2. 维护 k-1 个候选元素和计数器
  3. 投票阶段:
    • 匹配候选 → 对应计数器加1
    • 计数器为0 → 设为新候选
    • 都不匹配 → 所有计数器减1
  4. 验证候选元素的实际出现次数

实际应用场景

  1. 大数据分析:从海量数据中找出高频项
  2. 网络流量监控:检测异常高频访问
  3. 推荐系统:识别热门内容
  4. 日志分析:查找频繁出现的错误类型
  5. 选举系统:统计多候选人得票情况

边界情况处理

  1. 候选元素为 null 的情况

    if (candidate1 != null && num == candidate1)
    
  2. 数组长度小于3

    • 当 n < 3 时,⌊n/3⌋ = 0,所有元素都满足条件
    • 但实际需统计出现次数 > 0 的元素(根据定义)
  3. 没有满足条件的元素

    // 验证阶段会过滤掉不满足条件的候选
    if (count1 > n/3) result.add(candidate1);
    

总结

扩展摩尔投票法展示了算法设计的精妙之处:

  1. 数学洞察:利用问题约束(最多 k-1 个候选)
  2. 空间优化:O(1) 空间解决统计问题
  3. 高效性:O(n) 时间复杂度
  4. 通用性:可扩展为 n/k 问题

掌握这种扩展思维,能帮助我们在面对各类统计问题时,设计出高效的空间优化算法。摩尔投票法不仅是解决多数元素问题的利器,更是算法设计中"以空间换时间"思想的经典体现。

思考挑战:如何扩展该算法处理出现次数超过 n/4 的情况?欢迎在评论区分享你的解决方案!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907253.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git:现代软件开发的基石——原理、实践与行业智慧·优雅草卓伊凡

Git&#xff1a;现代软件开发的基石——原理、实践与行业智慧优雅草卓伊凡 一、Git的本质与核心原理 1. 技术定义 Git是一个分布式版本控制系统&#xff08;DVCS&#xff09;&#xff0c;由Linus Torvalds在2005年为管理Linux内核开发而创建。其核心是通过快照&#xff08;Sna…

程序人生-hello’s P2P

计算机系统 大作业 题 目 程序人生-hello’s P2P 专 业 计算机与电子通信类 学   号 2023111990 班   级 23L0514 学 生 袁骋 指 导 教 师 史…

Java设计模式之设计原则

Java设计模式 Java设计模式主要原则是开闭原则&#xff0c;即对扩展开放&#xff0c;对修改关闭。由此衍生出5大原则&#xff1a;单一职责原则&#xff0c;里式替换原则&#xff0c;迪米特原则&#xff0c;接口隔离职责&#xff0c;依赖倒置原则。1、开闭原则 开闭原则&#x…

使用 ssld 提取CMS 签名并重签名

拿SpringBoard的cms签名和entitlements.xml&#xff0c;对tihook.dylib进行重签名 工具来源&#xff1a;https://github.com/eksenior/ssld

WebFuture:测试邮件发送失败

问题描述&#xff1a;测试邮件发送失败 问题分析&#xff1a; 查看报错是模拟发送邮件请将systemsettings.json中的EnabledMail设为false&#xff01; 解决方案&#xff1a; 网站根目录找到Configuration&#xff0c;如下图所示&#xff0c;将systemsettings.json中的Enabled…

LiveNVR 直播流拉转:Onvif/RTSP/RTMP/FLV/HLS 支持海康宇视天地 SDK 接入-视频广场页面集成与视频播放说明

LiveNVR直播流拉转&#xff1a;Onvif/RTSP/RTMP/FLV/HLS支持海康宇视天地SDK接入-视频广场页面集成与视频播放说明 一、视频页面集成1.1 关闭接口鉴权1.2 视频广场页面集成1.2.1 隐藏菜单栏1.2.2 隐藏播放页面分享链接 1.3 其它页面集成 二、播放分享页面集成2.1 获取 iframe 代…

12. CSS 布局与样式技巧

在前端开发中&#xff0c;CSS 是控制页面样式和布局的核心技术。本文总结了 CSS 布局中的关键概念和实用技巧&#xff0c;包括 overflow 属性、背景图片处理、精灵图技术、display 属性、浮动布局以及清除浮动的方法。 一、overflow 属性详解 overflow 属性用于控制当元素内容…

OpenCV---Canny边缘检测

一、基本概念与核心作用 Canny边缘检测是计算机视觉中最经典的边缘检测算法之一&#xff0c;由John Canny于1986年提出。其核心目标是在噪声图像中提取精确、单像素宽、连续的边缘&#xff0c;广泛应用于&#xff1a; 目标检测预处理&#xff08;如Robomaster中灯条、装甲板的…

提效-点击跳转到源码

1、localhost项目 例如【鲸岛】这个中台项目启动地址是localhost。 使用chrome中的【click-to-react-component 】扩展&#xff0c; alt 鼠标左键 选择dom后跳转到对应文件。 click-to-react-component的原理&#xff08;来自ai&#xff09; click-to-react-component 的工作…

FeignClient发送https请求时的证书验证原理分析

背景 微服务之间存在调用关系&#xff0c;且部署为 SSL 协议时&#xff0c;Feignt 请求报异常&#xff1a; Caused by: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find vali…

性能优化关键:link、script和meta的正确打开方式

link 标签的主要属性及其作用 属性是否必填作用描述示例值rel是定义当前文档与链接资源的关系&#xff08;必须属性&#xff09;。常见值&#xff1a;stylesheet, icon, preload, preconnect 等。rel"stylesheet" rel"icon"href是指定链接资源的URL。href…

Linux `less` 命令深度解析与高阶应用指南

Linux `less` 命令深度解析与高阶应用指南 一、核心功能解析1. 基本作用2. 与类似工具对比二、选项系统详解1. 常用基础选项2. 高阶选项组合三、高阶应用场景1. 日志分析系统2. 代码审查系统3. 数据管道处理四、特殊文件处理1. 大文件优化查看2. 二进制文件分析五、交互式命令大…

影刀RPA-20-高级操作题2

一、题目 二、链接 方法一&#xff1a;影刀应用分享: 高级考试题2-第二次 方法二&#xff1a;影刀应用分享: 高级考试题2 三、代码 方法一&#xff1a; import xbot from xbot import print, sleep from .import package from .package import variables as glv from xbot…

C# NX二次开发-获取面法向和UV等数据

通过ufun函数UF_MODL_ask_face_props可以获取到面的法向数据和UV和半径等数据。 代码如下&#xff1a; double[] uvs new double[4];double[] param new double[2];double[] point new double[3];double[] u1 new double[3];double[] v1 new double[3];double[] u2 new d…

SpringBoot整合Sa-Token:实现RBAC权限模型

Java系列文章 文章目录 Java系列文章前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备 二、表结构设计2.1 ER图示例2.2 数据库表设计2.2.1 用户表2.2.2 角色表2.2.3 部门表2.2.4 权限表 三、SpringBoot整合Sa-Token3.1 sa-token基础配置3.1.1 Maven配置3…

工商业储能的“智慧大脑”:解密 Acrel-2000ES EMS 的核心功能与价值

安科瑞电气顾强 市场背景&#xff1a;工商业储能加速崛起 2022年中国已并网的储能项目中&#xff0c;用户侧并网占比为8.36%&#xff0c;其中工商业储能占据了用户侧高达98.6%的份额。驱动这一市场发展的关键因素日益显著&#xff1a; 1.峰谷价差扩大&#xff1a; 全国各省市…

vue+threeJs 根据屏幕调整gltf模型的大小、重心、并更换骑车整体颜色

嗨&#xff0c;我是小路。今天主要和大家分享的主题是“vuethreeJs 根据屏幕调整gltf模型的大小、重心、并更换骑车整体颜色”。 项目案例示意图 1.整体更换gltf模型的颜色 定义&#xff1a;整体代码如下。颜色是事先设定的 const colorAry reactive(["rgb(21…

03 基于 java udp 做一个dns服务器 和 一个dns代理服务器

前言 这个也是 来自于一个朋友的需求 最终的目的是实现一个 dns 代理服务器, 当然 这本质也是一个 dns 服务器 并且 dns 代理服务器是依赖于 一个 dns 服务器的, 因此 顺便给一个 dns 服务器的 demo 这里 主要是 基于 udp 的一个 dns 请求, 响应数据的交互 dns 服务器 …

【HITCSAPP 哈工大计算机系统期末大作业】 程序人生-Hello’s P2P

计算机系统 大作业 题 目 程序人生-Hello’s P2P 专 业 计算机与电子通信类 学   号 2023112915 班   级 23L0505 学 生 杨昕彦 指 导 教 师 刘宏伟 计算机科学…

第十周作业

一、CSRF 1、DVWA-High等级 2、使用Burp生成CSRF利用POC并实现攻击 二、SSRF&#xff1a;file_get_content实验&#xff0c;要求获取ssrf.php的源码 三、RCE 1、 ThinkPHP 2、 Weblogic 3、Shiro