题目描述
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
解法一:
1、定义一个数组num[ ]存放数组中的数字出现的次数
2、遍历数组,每遇到一个数字,假设为i,就将num[ ]中的第i项的值+1
3、判断并返回num[ ]中出现次数大于数组长度一半的数字(注意:此处应该返回的是项数i的值)
时间复杂度为O(n)
//数组中出现次数超过一半的数字
int MoreThanHalfNum_Solution(vector<int> numbers) {
size_t num[1000] = { 0 };
for (auto i : numbers)
{
num[i]++;
if (num[i] > (numbers.size() / 2))
return i;
}
return 0;
}
解法2:
使用哈希表,步骤和解法1相似
时间复杂度为O(n)
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
map<int, int> m;
for (int i = 0; i < numbers.size(); ++i) {
m[numbers[i]]+=1;
if(m[numbers[i]]>numbers.size()/2)
return numbers[i];
}
return 0;
}
};
解法3:摩尔投票算法
摩尔投票算法主要用来解决:找到 n 个数中出现次数超过 n/2 的数的问题,
具体实现就是标记第一个出现的成员,并且定义一个计数器count:
1、如果后序出现相同成员,则count+1;
2、如果出现不同成员,则count-1;
3、如果计数器小于0,则更换被标记的成员
4、返回最后被标记的成员
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int target=0; //标记成员
int count =0; //计数器
for(int i=0;i<numbers.size();i++)
{
if(count==0)
{
++count;
target=numbers[i];
}
else if(target==numbers[i])
{
++count;
}
else
{
--count;
}
}
return target;
}
};