169. 多数元素 & 面试题 17.10. 主要元素 ●

169. 多数元素 ● & 面试题 17.10. 主要元素 ●

描述

数组中占比超过一半的元素称之为主要元素。给你一个 整数 数组,找出其中的主要元素。
若没有,返回 -1 。

请设计时间复杂度为 O(N) 、空间复杂度为 O(1) 的解决方案。

示例

输入:[1,2,5,9,5,9,5,5,5]
输出:5

输入:[3,2]
输出:-1

题解

1. 哈希表
  • 时间复杂度:O(n)
  • 空间复杂度:O(n)
2. 排序

将数组 nums 排序,主要元素一定在数组中点。(数组中点不一定是主要元素,需要再遍历一次判断)

  • 时间复杂度:O(nlogn)
  • 空间复杂度:O(1)
3. Boyer-Moore 摩尔投票算法

Boyer-Moore 投票算法的基本思想是:
在每一轮投票过程中,从数组中删除两个不同的元素,直到投票过程无法继续,此时数组为空或者数组中剩下的元素都相等。

  • 如果数组为空,则数组中不存在主要元素;
  • 如果数组中剩下的元素都相等,则数组中剩下的元素可能为主要元素。

Boyer-Moore 投票算法的步骤如下:

  1. 维护一个候选主要元素 c a n d i d a t e candidate candidate 和候选主要元素的出现次数 c n t cnt cnt,初始时 c a n d i d a t e candidate candidate 为任意值, c n t = 0 cnt=0 cnt=0

  2. 遍历数组 n u m s nums nums 中的所有元素,遍历到元素 num 时,进行如下操作:

    • 如果 cnt == 0,则将 num 的值赋给 candidate,否则不更新 candidate 的值;
    • 如果 num == candidate,则将 cnt 加 1,否则将 cnt 减 1。
  3. 遍历结束之后,得到一个可能为主要元素的值 candidate,我们无法确定最后剩下的 candidate 是经过多次抵消后剩余的主要元素,还是只是不存在主要元素的数组中的无效随机元素

  4. 第二次遍历, 统计 candidate 的出现次数并进行比较。

为什么当数组中存在主要元素时,Boyer-Moore 投票算法可以确保得到主要元素?

在 Boyer-Moore 投票算法中,遇到相同的数则将 ount 加 1,遇到不同的数则将 count 减 1。根据主要元素的定义,主要元素的出现次数大于其他元素的出现次数之和,因此在遍历过程中,主要元素和其他元素两两抵消,最后一定剩下至少一个主要元素,此时 candidate 为主要元素,且 count ≥ 1

  • 时间复杂度:O(n)
  • 空间复杂度:O(1)
class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int candidate = nums[0], cnt = 0;
        for(int num : nums){
            if(cnt == 0){
                candidate = num;			// 更新candidate
            }
            if(candidate == num){			// 更新cnt 
                ++cnt;
            }else{
                --cnt;
            }
        }
        cnt = 0;
        for(int num : nums){
            if(num == candidate) ++cnt;		// 统计 candidate 次数
        }
        if(2 * cnt > nums.size()){			// 判断次数
            return candidate;
        }
        return -1;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值