数组-寻找过半数字
十二月 19, 2021
2391
每日一题,提升自己。今天分享一道关于寻找过半数字的题目,且听我细细道来。
数组 - 寻找过半数字
1. 题目描述
数组中一定有一个数字出现的次数超过数组长度的一半,请找出这个数字。你可以假设数组是非空的,并且给定的数组总是存在多数元素。
示例:
输入:[1, 2, 3, 2, 2, 2, 5, 4, 2]
输出:2
提示:
1 <= 数组长度 <= 50000
2. 解题思路
2.1 思路一
本题可以用排序法来解决,因为数组中一定有一个数字超过数组长度一半,那么排序之后的数组,中间元素就是要寻找的数字。
复杂度:
- 时间复杂度:O(nlogn)。
2.2 思路二
本题可以用哈希计数法来解决,在遍历数组的同时,使用当前数字作为key,当前数字出现的次数存为value,存放在一个HashMap中,统计每个数字出现的次数。统计完成之后再遍历一下HashMap,找到value最大的那个值,此时对应的key就是超过数组长度一半的数字。
复杂度:
- 时间复杂度:O(n)。
2.3 思路三
还有一种方式可以解决本题,那就是摩尔投票,遍历数组,使用count进行计数,记录当前出现的数字为cur,如果遍历到数字与cur相等,则count加一,否则就减一。当count减到0点时候,将cur修改为当前正在遍历的数字,通过增减抵消的方式,最终剩下的数字就是要寻找的过半数字。这种方法相对于前两种来说是最优的。
摩尔投票算法是基于这个事实:每次从序列里选择两个不相同的数字删除掉(或称为“抵消”),最后剩下一个数字或几个相同的数字,就是出现次数大于总数一半的那个。
复杂度:
- 时间复杂度:O(n)。
- 空间复杂度:O(1)。
3. 算法流程
3.1 思路一流程
排序法:
- 首先对数组进行排序。
- 返回排序过后的数组的中间数字。
3.2 思路二流程
哈希计数法:
- 创建一个HashMap用于存放数据。
- 遍历数组,判断HashMap中是否存在等于该数字的key。
- 如果不存在,则将当前数字作为key存入,value等于1。
- 如果存在,将当前数字对应的value加一。
- 遍历HashMap,找出最大的value值。
- 返回value对应的key。
3.3 思路三流程
摩尔投票法:
- 初始化当前数cur=0,当前计数器count=0。
- 遍历数组,如果count==0,那么将遍历的当前数赋值给cur,count++。
- 如果cur等于遍历的当前数,count++。
- 否则count–。
- 返回cur。
4. 代码实现
4.1 思路一代码
Java代码实现如下:
1 |
|
4.2 思路二代码
Java代码实现如下:
1 |
|
4.3 思路三代码
Java代码实现如下:
1 |
|
- 本文作者:byFan
- 本文链接:http://byfan.xyz/2021/12/19/majorityElement/index.html
- 版权声明:本博客所有文章均采用 BY-NC-SA 许可协议,转载请注明出处!