数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
原先自己写的方法,这种方法在for循环中还有for循环,算法复杂度为 O(n2) O ( n 2 ) ,并不是一种好的方法:
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int current = 0;
int times = 0;
int length = numbers.size();
int i = 0;
for(; i<length; i++)
{
current = numbers[i];
for(int j = 0; j<length; j++)
{
if(current == numbers[j])
{
times++;
}
else
{
times--;
}
}
if(times>0)
return current;
else
times=0;
}
return 0;
}
};
参考剑指offer中的思想,设置两个int值:current用于记录当前猜测的数,count用于记录该数出现的次数,遍历数组一遍,如果遍历过程中的当前值与猜测数current相同,则count+1,如果不同,则count-1,如果当前循环中count=0,则令当前遍历值为新的current值。最终,如果current对应的count值不为大于1,则说明该数current是满足题意的数。
class Solution {
public:
int MoreThanHalfNum_Solution(vector<int> numbers) {
int current = numbers[0];
int count = 0;
int size = numbers.size();
for(int i = 0; i<size; ++i)
{
if(count == 0)
{
current = numbers[i];
count = 1;
// continue;
}
//if(current == numbers[i])此处不应该用if,如果用if需要用continue
else if(current == numbers[i])
{
count++;
// continue;
}
// if(current != numbers[i])
else
{
count--;
// continue;
}
}
/* if(count > 1) //这样判断不行,反例:数组为123222542共九个数(数组元素个数不一定为偶数),此时循环完之后count=1,程序输出0,实际应输出2
return current;
else
return 0;
*/
count = 0;
for(int i = 0; i<size; i++)
{
if(numbers[i] == current)
count++;
}
if(count>(size/2))
return current;
else
return 0;
}
};