找一个数组中的众数-boyer-moore

主要从数学的角度思考问题。

先判断count的数值,那么count == 0,那么该元素就是候选众数。

再比较元素num与候选众数的值,若一致,count自增,反之自减。

候选众数会成为最终的我们要找的众数。

代码:

Integer candidate = null;//null代表数组没有众数
int count = 0;//既然有默认数字0,用基本数据类型便可,有null的需求才用包装
for(num:nums){
    if(count == 0){
        candidate = num;
    }
    count += (candidate == num) ? 1:-1; 
}
return candidate;

至于为什么会有这个解法,说到底是一种数学规律,暂且不论,先用起来。

count用来计算某个元素出现的次数。

初始化候选参数,如果元素与候选参数相等,那该元素出现的次数就多了一次。

count从正数变成0,说明有一个参数(这个参数未必是众数,只是和候选数不同)出现的次数多于候选参数。

为什么count一定是正数?因为count==0的时候,会设置生成另外一个候选参数。

count除了用来计算候选参数出现的次数,还有什么其它含义呢?

从遍历到当前元素打止,用value代表众数出现的次数相对于非众数出现的次数多了或者少了多少个。假设maj就是真实众数,拿当前访问的元素与其比较。

知道真实众数,使用value的概念辅助验证,计算众数比非众数多出现的次数。

两个概念,真实众数、候选众数,拿当前遍历的元素与这两个概念对应的元素比较。

一个奇妙的性质,假设当前候选元素是真实众数,count和value对应的值相同。而如果当前候选元素不是真实众数,那么count和value互为相反数。

题解有个大前提,数组必须只包含唯一的众数。

在知道数组的真实众数的条件下,提出value(众数相对非众数多出来的次数)的概念用于辅助证明,通过比对value和count的值得出一个奇妙的性质。

最后一步,count==value且两个参数大于0就能证明candidate就是真实众数么?

value只是用来辅助证明count解法是可行的。

通过规律找性质,用性质反过来证明这个候选众数就是真实众数。

提出value的概念,value和maj绑定>比较value和count的值,发现count和value的值要么相同,要么相反(candidate==maj的时候,两者相同,否则相反)> 提出"一段"的概念,在这一段中,count是按照x是否和candidate相同来加减的,而candidate若和maj一致,发现value的变化和count是保持一致的(用来证明candaidate是maj)。否则互为相反数。(这个发现用来证明,正因为value为正数,count不为负数,所以count和value绝不会互为相反数,所以只可能value==count,而正因为count == value,所以最后"一段",value和count的变化是同步的,而正因为count和value的变化是同步的,所以可以证明candidate就是maj)。

用自己发现的性质规律去证明这种做法的可行性。

value为正数,说明众数的个数一定比非众数至少多一个,这是要求,隐藏要求,况且在思路里面,众数+1,非众数-1,和大于0,显然,有一个隐藏的要求是非众数的个数一定比众数的个数少。value的概念是多的次数,不考虑0和负数,就算是,这种解法也没有问题。不过没有证明。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值