JZ39 数组中出现次数超过一半的数字
题目:数组中出现次数超过一半的数字_牛客题霸_牛客网
给一个长度为 n 的数组,数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。
例如输入一个长度为9的数组[1,2,3,2,2,2,5,4,2]。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。
数据范围:n≤50000n≤50000,数组中元素的值 0≤val≤100000≤val≤10000
要求:空间复杂度:O(1)O(1),时间复杂度 O(n)O(n)
一、方法一:摩尔投票算法
核心思想:在数组中,如果一个数据出现的次数超过了该数组的长度的一半,那就意味着,它出现的次数,比其他元素出现的次数的总和还要多。
-
初始化阶段
-
选择一个候选元素(candidate)
-
设置计数器 count = 1
-
-
遍历阶段
-
遍历数组中的每个元素
-
如果当前元素等于候选元素,count++
-
如果当前元素不等于候选元素,count--
-
如果 count 减到 0,更换候选元素为当前元素,并重置 count = 1
-
代码如下:
int MoreThanHalfNum_Solution(vector<int>& numbers) {// write code hereint candidate = numbers[0];int count = 0;for(auto num : numbers){if(candidate == num){++count;}else {--count;}if(count == 0){candidate = num;count = 1;}}return candidate;}
二、方法二:排序法
核心思想:将数组排序好后,众数肯定在序列的中间。然后可以依次遍历,寻找中间的众数进行验证。
代码:
int MoreThanHalfNum_Solution(vector<int>& numbers){sort(numbers.begin() ,numbers.end());int cond = numbers[numbers.size()/2];return cond;}
这里有个问题:就是 sort 排序的时间复杂度不稳定,当处于坏情况时,它的时间复杂度是O(NlogN) ,违背了题目的限制。但是这里的题目给的数据很少,几乎和O(N)没有区别。