Boyer-Moore摩尔投票法

16 篇文章 0 订阅

基本思想

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

如果数组为空,则数组中不存在主要元素(数组中占比超过一半的元素);

如果数组中剩下的元素都相等,则数组中剩下的元素可能为主要元素。

算法步骤

  1. 先用stream流将数组排序后转化成列表list
  2. 定义两个变量i和j作为指针,i指向list队头,j指向list队尾。
  3. 遍历list,如果指针下标对应元素不相等,则删除这两元素(这里为什么删除队尾的时候要-1,因为已经删了队头i,此时list长度发生了变化,j不-1就会越界),并重新让i和j指向队头队尾;如果相等则在list不越界情况下,i++,j--。为了提高效率,当i==j时说明指向同一元素直接跳出循环。
  4. 循环结束后,判断list是否为空,为空说明list的元素都不一样,没有主要元素,直接返回-1;若不为空,说明list里都是相同的元素了,取第一个,遍历原数组,统计第一个元素在原数组中出现的次数,若小于原数组长度的一半(这里要用nums.length/2.0,为什么是2.0?因为除法是向下取整,避免出现误差要精确一点)则返回-1;否则说明list中的元素是主要元素。

代码如下

remove的时候注意remove有2种参数,一种是下标,一种是元素。因为元素类型正好是Integer,所以不管填下标或是元素都会默认成下标。正好符合我们的需求。若你需要删除元素,看我这篇文章Java增强for循环遍历集合删除指定值不安全问题_list<integer>增强for删除一个内容-CSDN博客

List<Integer> list = Arrays.stream(nums).sorted().boxed().collect(Collectors.toList());
        for(int i=0, j=list.size()-1;i<list.size()&&j>0;){
            if(list.get(i)-list.get(j)!=0){
                // 移除下标为i和j的元素
                list.remove(i);
                list.remove(j-1);
                i=0;
                j=list.size()-1;
                
            }else{
                if(i<list.size()) i++;
                if(j>0) j--;
                
            }
            if(i==j) break;
        }
        if(list.isEmpty()) return -1;
        int count=0;
        for(int num:nums){
            if(num==list.get(0)) count++;
        }
        if(count<nums.length/2.0) return -1;
        return list.get(0);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值