题目:
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
思路:
方法一:最简单的思路就是将这一组数进行排序,记录下中位数的值,定义一个计数器,遇到和这个数相同的数,就进行加一,最后比较计数器的值与数组长度一半的大小,如果大于就返回中位数的值,如果小于说明不存在返回0。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int size = numbers.size();
if(size == 0)
return 0;
sort(numbers.begin(), numbers.end());
int mid = numbers[size/2];
int count = 0;
for(int i=0 ;i<size; ++i){
if(numbers[i]==mid)
++count;
}
return (count>size/2) ? mid : 0;
}
};
方法二:也可以借助STL中的容器进行实现,unordered_map存放键值对,一个存放数组中的值,一个记录出现次数。最后遍历进行比较,超过一半,我们就返回其值。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty())
return 0;
unordered_map<int, int> res;
for(int i=0; i<numbers.size(); i++){
res[numbers[i]]++;
}
int size = (numbers.size())/2;
unordered_map<int, int>::iterator it = res.begin();
while(it != res.end()){
if((*it).second > size)
return (*it).first;
*it++;
}
return 0;
}
};
方法三:
这种方法,定义了一个time来统计次数,一开始初始化为1,再定义了一个res作为最后的结果。遍历一遍数组,如果下一个数和res相同,time加1;如果time为0,就重新开始计数,time重新记为1;如果下一个数和res不同,time减一。
最后遍历一遍,将res的值与每个值进行比较,如果相等,计数器加一,最后进行比较,如果大于数组个数的一半,就返回res,否则返回0。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
if(numbers.empty())
return 0;
int time = 1;//次数
int res = numbers[0];
int size = numbers.size();
for(int i=1; i<size; i++){
if(res == numbers[i])
time++;
else if(time == 0)//重新开始计数
{
res = numbers[i];
time = 1;
}
else
time--;
}
int count = 0;
for(int i=0 ;i<size; i++){
if(numbers[i] == res)
count++;
}
return (count*2>size)?res:0;
}
};