JZ39 数组中出现次数超过一半的数字 (Boyer-Moore 投票算法)候选法
数组中出现次数超过一半的数字_牛客题霸_牛客网
描述
给一个长度为 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)
输入描述:
保证数组输入非空,且保证有解
示例1
输入:
[1,2,3,2,2,2,5,4,2]返回值:2示例2
输入:
[3,3,3,3,2,2,2]返回值:3示例3
输入:
[1]返回值:1
哈希
class Solution { public: int MoreThanHalfNum_Solution(vector<int> numbers) { map<int, int> mp; int n = numbers.size(); for(auto e : numbers) { mp[e]++; if(mp[e] > n/2) return e; } return 0; } };
排序
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
sort(numbers.begin(), numbers.end());
return numbers[numbers.size() / 2];
}
};
(Boyer-Moore 投票算法)
想象一下,如果把这些数字当做人种,一个数字和另外一个数字打了起来,同归于尽。最后剩下的是不是人数最多的那种人。这里要满足一个条件:某类人的数目一定要大于总人数的一半。
算法步骤:我们选择输入数组中第一个元素作为候选元素candidate,并设置其出现次数为count=1。随后遍历数组。当遇到与candidate相同的元素,count+1;不同的元素,count-1。当count为0的时候,选择下一个元素为候选元素,并且置count=1。遍历到数组的最后,剩下的candidate就是要求的结果。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int>& numbers) {
int candidate = numbers[0];
int count = 1;
for(int i = 1; i < numbers.size(); i++)
{
if(numbers[i] == candidate)
count++;
else
count--;
if(count == 0)
{
candidate = numbers[i+1];
}
}
return candidate;
}
};