Boyer-Moore投票算法(基础版)

本文详细解读LeetCode中的Majority Element问题,通过基础投票算法和Boyer-Moore改进版讲解如何找出数组中出现次数超过半数的元素,涉及理论推导和代码实现分析。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

leetcode-Majority Element

在这里插入图片描述

AC代码(投票算法基础版)

class Solution {
    public int majorityElement(int[] nums) {
        int count = 0;
        int candiadate = 0;
        for(int i : nums)
        {
            if(count == 0) {
                count++;
                candiadate = i;  //更换candiate
            }
            else if(i == candiadate)
                count++;
            else count--;
        }
        return candiadate;
    }
}

Boyer-Moore投票算法(基础版)

  • 用于求解上述主要元素问题,即数组中出现此时大于一半多的元素。
  • INTUITION:维护一个候选candiate,当遇到是candiate值得时候计数器增加,当遇到不是candiate的时候计数器减1.当计数器减到0时更换candiate。最后返回的candiate即为候选值。
  • 由于count=0时才会设置candiate,因此我们证明最后一次count=0时,进入循环,设置的candiate一定是这个主要元素。
    • 如果不是这个主要元素,那么这最后一次从count == 0到退出循环,最终有count>=0 ,且这最后一部分candidate(不是要找的主要元素)出现的次数一定比一半还多(否则就不是最后一次count =0时进入循环),且这个candidate出现的次数最少为1次。从整个序列中除去最后一部分所有的candidate,元素最多剩下n-1个。一般的,如果假设最后一部分元素有k个,那么candidate至少出现的次数是 ⌈ k / 2 ⌉ \lceil k/2 \rceil k/2次(分最后一部分总个数为奇数和偶数讨论),否则这不是最后一次进入循环时的count = 0。如果这最后一部分剩余的元素都是主要元素,给出了主要元素在最后一部分的最多个数为 k − ⌈ k / 2 ⌉ k - \lceil k/2 \rceil kk/2
    • 显然前面部分所有的元素为n - k个。
    • 由于前面的每一个部分,都是在count = 0进入循环重新候选,再次count=0时结束这个部分,根据算法流程,显然每个部分的数量都是偶数(所以前面所有部分的元素个数总和为偶数
    • 同时,前面每一部分的candiadate都在每个部分中恰好出现一半。如果这些candiate都是我们要求的主要元素,那么在前面所有部分这些主要元素出现的次数为 n − k 2 \frac{n - k}{2} 2nk次。
    • 于是主要元素出现总次数的最大值次数为 k − ⌈ k / 2 ⌉ + n − k 2 = n + k 2 − ⌈ k / 2 ⌉ k - \lceil k/2 \rceil +\frac{n - k}{2}=\frac{n+k}{2}- \lceil k/2 \rceil kk/2+2nk=2n+kk/2
    • 考虑关系: n + k 2 − ⌈ k / 2 ⌉ ≤ n + k 2 − k 2 = n 2 < ⌊ n 2 ⌋ + 1 \frac{n+k}{2}- \lceil k/2 \rceil \leq \frac{n+k}{2} - \frac{k}{2} = \frac{n}{2} < \lfloor \frac{n}{2} \rfloor + 1 2n+kk/22n+k2k=2n<2n+1
      由于题干中给出了主要元素至少出现 ⌊ n 2 ⌋ + 1 \lfloor \frac{n}{2} \rfloor + 1 2n+1次的这个前提,而在假设最后一部分的candiate不是主要元素的条件下,我们导出了主要元素出现的最大次数为 n + k 2 − ⌈ k / 2 ⌉ \frac{n+k}{2}- \lceil k/2 \rceil 2n+kk/2小于题干给出的最小出现次数,矛盾。
    • 因此假设不成立,最终得到的candiate就是题干中所述的主要元素。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值