写点什么

【刷题第 16 天】数组中出现次数超过一半的数字

作者:白日梦
  • 2022 年 5 月 23 日
  • 本文字数:800 字

    阅读完需:约 3 分钟

一、题目描述:

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:

输入: [1, 2, 3, 2, 2, 2, 5, 4, 2]输出: 2
复制代码

二、思路分析:

哈希表法

最简单的方法应该就是利用哈希表了,我们定义一个 hash(javascript 中应该是 map),键值对分别存储数字和数字出现次数,同时可以维护一个出现频数的最大值(可以省去遍历完毕后再遍历 hash 获取最大频次的时间),最后我们可以直接判断频次最大值/数组长度得比值是否大于 1/2 即可

摩尔法

博耶-摩尔多数投票算法( Boyer–Moore majority vote algorithm ),中文常作多数投票算法、摩尔投票算法等,是一种用来寻找一组元素中占多数元素的常数空间级时间复杂度算法。

摩尔投票法核心在于投票与计数两个阶段。例如我们举下面的案例: 1 2 2 2 3 来理解一下摩尔投票法。

  • 投票阶段:首先我们选取第一个元素为候选人,维护一个 count 初始值为 0 遍历数组,当元素与候选人不同是, count --,若相同 count ++当 count 为 0 时,更换候选人

  • 计数阶段:投票结束后,如果 count 非 0,则证明此候选人有概率占据总数得一半之上例如 [1,2,2,1,3,3] 这种,前面两个候选人选票互相内耗了,第三个候选人也没有达到总票数的一半,因此我们需要进行计数

三、AC 代码:

var majorityElement = function(nums) {    let cand = nums[0];    let count = 0;    nums.forEach(val => {        // 如果count = 0,那么则替换候选人        if(!count) {            cand = val;        }        // 如果当前值等于候选人,count ++;否则 count --        if(cand === val) {            count++;        } else {            count--;        }    }    return nowCandidate;};
复制代码

四、总结:

摩尔投票法还是挺有意思得一种方法,我在查阅资料是发现此种方法还能用于同时投出两个候选人或者多个候选人,有机会去做一下该题目。


发布于: 刚刚阅读数: 4
用户头像

白日梦

关注

还未添加个人签名 2022.03.10 加入

还未添加个人简介

评论

发布
暂无评论
【刷题第16天】数组中出现次数超过一半的数字_5月月更_白日梦_InfoQ写作社区