查找数组中超过出现次数超过一半的数字(找发帖水王)

来源:互联网 发布:剑三高冷道姑捏脸数据 编辑:程序博客网 时间:2024/06/09 20:05

题目

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

解决方案:

1.如果无序,那么我们是不是可以先把数组中所有这些数字先进行排序,至于选取什么排序方法则不在话下,最常用的快速排序ON*logN)即可。排完序呢,直接遍历。在遍历整个数组的同时统计每个数字的出现次数,然后把那个出现次数超过一半的数字直接输出,题目便解答完成了。总的时间复杂度为ON*logN+N)。我们发现,一个数字在数组中的出现次数超过了一半,那么在排好序的数组索引的N/2(从零开始编号),就一定是这个数字。自此,我们只需要对整个数组排完序之后,然后直接输出数组中的第N/2处的数字即可,这个数字即是整个数组中出现次数超过一半的数字,总的时间复杂度由于少了最后一次整个数组的遍历,缩小到ON*logN)。

2.要缩小总的时间复杂度,那么就用查找时间复杂度为O1),事先预处理时间复杂度为ON)的hash。哈希表的键值(Key)为数组中的数字,值(Value)为该数字对应的次数。然后直接遍历整个hash表,找出每一个数字在对应的位置处出现的次数,输出那个出现次数超过一半的数字即可。Hash表需要ON)的开销空间,且要设计hash函数。

3.如果每次删除两个不同的数(不管是不是我们要查找的那个出现次数超过一半的数字),那么,在剩下的数中,我们要查找的数(出现次数超过一半)出现的次数仍然超过总数的一半。通过不断重复这个过程,不断排除掉其它的数,最终找到那个出现次数超过一半的数字。这个方法,免去了上述思路一、二的排序,也避免了思路三空间ON)的开销,总得说来,时间复杂度只有ON),空间复杂度为O1),不失为最佳方法。


加强版水王:找出出现次数刚好是一半的数字 

关于加强版水王的题我有个想法可以扫描一遍数组就解决问题:
    首先,水王占总数的一半,说明总数必为偶数;其次,最后一个元素或者是水王,或者不是水王,因此只要在扫描数组的时候每一个元素都与最后一个元素做比较,如果相等则最后一个元素的个数加1,否则不处理。如果最后一个元素的个数为N/2,(N为数组元素个数)则它就是水王,否则水王就是前面N-1个元素中选出的candidate。