摩尔投票法(力扣- -229. 求众数 II)

文章目录

  • 摩尔投票法(力扣- -229. 求众数 II)
    • 一、题目描述
    • 二、分析
      • 摩尔投票法
      • 总结
    • 三、代码

一、题目描述

二、分析

  • 这道题如果用O(N)O(N)O(N)的空间复杂度来解决是非常简单的,但是题目要求:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题
  • 这里介绍摩尔投票法

摩尔投票法

  • 摩尔投票法,解决的问题是如何在任意多的候选人中,选出票数超过一半的那个人。注意,是超出一半票数的那个人。

  • 假设投票是这样的,[A, C, A, A, B](ABC 是指三个候选人)。

  • 第一张票与第二张票进行对坑,如果票不同则互相抵消掉

  • 接着第三票与第四票进行对坑,如果票相同,则增加这个候选人的可抵消票数

  • 这个候选人拿着可抵消票数与第五张票对坑,如果票不同,则互相抵消掉,即候选人的可抵消票数 -1

  • 图解

看完上面的图片之后,相信已经理解摩尔投票法是如何选取一个最有希望的候选人的

  • 猪猪猪猪猪猪意

  • 上面最后得道的结果并不意味着这个候选人的票数一定能超过一半,例如 [A, B, C] 的抵消阶段,最后得到的结果是 [C,1],C 候选人的票数也未能超过一半的票数。

  • 这里有一个优化,如果最后得到的可抵消票数是 0 的话,那他已经无缘票数能超过一半的那个人了。因为本来可能有希望的,但是被后面的一张不同的票抵消掉了。所以,在这里可以直接返回结果,无需后面的计算了。

  • 如果最后得到的抵消票数不为 0 的话,那说明他可能希望的,这是我们需要一个阶段来验证这个候选人的票数是否超过一半—— 计数阶段。

  • 所以摩尔投票法分为两个阶段:抵消阶段和计数阶段

  • 抵消阶段:两个不同投票进行对坑,并且同时抵消掉各一张票,如果两个投票相同,则累加可抵消的次数;

  • 计数阶段:在抵消阶段最后得到的抵消计数只要不为 0,那这个候选人是有可能超过一半的票数的,为了验证,则需要遍历一次,统计票数,才可确定

  • 摩尔投票法经历两个阶段最多消耗 O(2n)O(2n)O(2n) 的时间,也属于 O(n)O(n)O(n) 的线性时间复杂度,另外空间复杂度也达到常量级。

  • 理解摩尔投票法之后,我们再回到题目描述,题目可以看作是:在任意多的候选人中,选出票数超过⌊ 1/3 ⌋的候选人

  • 我们可以这样理解,假设投票是这样的 [A, B, C, A, A, B, C](ABC 是指三个候选人)。

  • 第 1 张票,第 2 张票和第3张票进行对坑,如果票都不同,则互相抵消掉;

  • 第 4 张票,第 5 张票和第 6 张票进行对坑,如果有部分相同,则累计增加他们的可抵消票数,如 [A, 2] 和 [B, 1];

  • 接着将 [A, 2] 和 [B, 1] 与第 7 张票进行对坑,如果票都没匹配上,则互相抵消掉,变成 [A, 1] 和 `[B, 0] 。

  • 图解

总结

  • 看完图片之后,是不是理解了,是不是也清晰了。

  • 如果至多选一个代表,那他的票数至少要超过一半(⌊1/2⌋)(⌊ 1/2 ⌋)(⌊1/2⌋)的票数;

  • 如果至多选两个代表,那他们的票数至少要超过(⌊1/3⌋)(⌊ 1/3 ⌋)(⌊1/3⌋) 的票数;

  • 如果至多选m个代表,那他们的票数至少要超过 (⌊1/(m+1)⌋)(⌊ 1/(m+1) ⌋)(⌊1/(m+1)⌋)的票数。

所以以后碰到这样的问题,而且要求达到线性的时间复杂度以及常量级的空间复杂度,直接套上摩尔投票法

三、代码

class Solution {public:vector<int> majorityElement(vector<int>& nums) {if(nums.empty()){return {};}//题目求的是满足元素个数大雨n / 3的元素,空间复杂度为O(1)//所以只需要按摩尔投票法记录2个元素的抵消个计数情况即可//第一个元素及票数情况int target1 = nums[0];int count1 = 0;//第二个元素及票数情况int target2 = nums[0];int count2 = 0;//遍历for(auto& e : nums){//如果和记录的元素中有相等的情况,更新他的计数if(e == target1){count1++;continue;}else if(e == target2){count2++;continue;}//程序走到这里代表没有和记录的元素相等的情况,代表//需要进行抵消操作//在进行抵消之前需要判断记录的元素是否有为0情况,因为如果为0//需要更新记录的元素if(count1 == 0){target1 = e;count1++;continue;}else if(count2 == 0){target2 = e;count2++;continue;}//抵消count1--;count2--;}//再对有可能满足情况的标记元素进行一次计数,进行验证int val1 = 0;int val2 = 0;for(auto& e : nums){if(e == target1){val1++;}else if(e == target2){val2++;}}vector<int> ret;if(val1 > nums.size() / 3){ret.emplace_back(target1);}if(val2 > nums.size() / 3){ret.emplace_back(target2);}return ret;}
};

摩尔投票法(力扣- -229. 求众数 II)相关推荐

  1. 【快乐水题】229. 求众数 II

    原题: 力扣链接:229. 求众数 II 题目简述: 给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 解题思路 1.通过哈希表来计算出现次数 2.if(k == (n ...

  2. java求众数_Java实现 LeetCode 229 求众数 II(二)

    229. 求众数 II 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2, ...

  3. LeetCode 229. 求众数 II(摩尔投票)

    1. 题目 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2,3] 输出: ...

  4. 229. 求众数 II

    求众数 II 给定一个大小为 n 的数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素. 说明: 要求算法的时间复杂度为 O(n),空间复杂度为 O(1). 示例 1: 输入: [3,2,3] 输出 ...

  5. [leetcode]229. 求众数 II

    解题思路:题目要求空间复杂度为O(1) 大于1/3的数不会超过2个,利用Boyer-Moore 投票算法找到数量最多的两个数,再检查下这俩个数的数量有没有超过1/3 class Solution {p ...

  6. leetcode 229. Majority Element II | 229. 求众数 II(找出现次数超过n/k的元素)

    题目 https://leetcode.com/problems/majority-element-ii/ 题解 思路来源于左程云<程序员代码面试指南> 问题描述 原问题:给定一个整型数组 ...

  7. 摩尔投票法(Boyer–Moore majority vote algorithm)

    参考资料 论文MJRTY A Fast Majority Vote Algorithm 算法演示网站 维基百科 算法解读 概述 摩尔投票法(Boyer–Moore majority vote algo ...

  8. C语言刷题之摩尔投票法

    目录 1.引入 2.摩尔投票算法 3.基本步骤 摩尔投票法分为两个阶段: 1.抵消阶段 2.检验阶段 4.代码实现 5.扩展沿伸 6.总结 1.引入 我们来看一个问题: 假设有一个无序数组长度为n,要 ...

  9. 动态规划和摩尔投票法

    动态规划 维基百科对动态规划(Dynamic programming,简称DP)的定义是一种在数学.管理科学.计算机科学.经济学和生物信息学中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问 ...

最新文章

  1. Python第一章-基础知识
  2. vue 自己写上传excel组件_vue结合elementui组件 el-upload 上传excel表格(二)
  3. 小学计算机课教学设计,小学信息技术教学设计三篇
  4. postman 无法正常返回结果 Could not get any response
  5. 进击的美少女!浙大学姐两年发14篇论文! 一作10篇,顶刊4篇!
  6. Dart 6-Day
  7. 【MyBatis笔记】0-MyBatis简介
  8. Unity 发布hololens注意事项
  9. ShipConstructor.2006v1.00.rar
  10. NOIP2016:换教室
  11. 本地音乐播放器Demo
  12. 基于javaweb的大学生兼职系统(java+springboot+jsp+mysql)
  13. Lesson28_网络编程
  14. 最优传输论文(一)Sliced Wasserstein Discrepancy for Unsupervised Domain Adaptation
  15. 服务器物理机如何实现系统快照,Lvm快照实现物理备份之自动化
  16. Python——迷宫生成和迷宫破解算法
  17. 19 Go Web 框架(二):框架技术详解
  18. pymongo count和count_documents效率对比
  19. 最小二乘公式推导(步骤详细,一看就会)
  20. IOC(控制反转)和DI(依赖注入)

热门文章

  1. des算法明文IP置换C语言编程,求助攻:C语言DES算法的实现程序有问题
  2. 获取二进制或者16/32位的某一位的值
  3. MySQL执行原理,逻辑分层、更改数据库处理引擎
  4. 工作章 - 小程序web-view分享 流泪爬坑记
  5. yield next和yield* next的区别
  6. JVM学习笔记(一)------基本结构
  7. 【VMCloud云平台】SCCM(五)创建第一个集合
  8. SOAP协议 访问Webservice
  9. HDU - 2389 Rain on your Parade(Hopcroft-Krap算法求二分图最大匹配)
  10. FZU - 2218 Simple String Problem(状压dp)