主元素定义
如果A是含有n个元素的数组,如果元素x在A中出现的次数大于n/2,则称X是A的主元素。
问题要求
如果A中的元素是可以排序的,设计一个时间复杂度为O(n)的算法。
思路分析
A数组中有个一个数字出现的次数超过了数组长度的一半,也就是有个数组的出现次数比其他所有数字出现次数的和还要多。
因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字,一个是次数。当我们遍历到下一个数字的时候,如果下一个数字和我们之前保存的数字相同,则次数加1。如果下一个数字和我们之前保存的数字不同,则次数减1。如果次数为零,我们需要保存下一个数字,并把次数设为1。由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。
bool g_bInputInvalid = false;
//////////////////////////////////////////////////////////////////////////
// Input: an array with "length" numbers. A number in the array
// appear more than "length / 2 + 1" times.
// Output: If the input is valid, return the number appearing more than
// "length / 2 + 1" times. Otherwise, return 0 and set flag g_bInputInvalid
// to be true.
//////////////////////////////////////////////////////////////////////////
int MoreThanHalfNum(int* numbers, unsigned int length)
{
if(numbers == NULL && length == 0)
{
g_bInputInvalid = true;
return 0;
}
g_bInputInvalid = false;
int result = numbers[0];
int times = 1;
for(int i = 1; i < length; ++i)
{
if(times == 0)
{
result = numbers[i];
times = 1;
}
else if(numbers[i] == result)
times++;
else
times--;
}
// verify whether the input is valid
times = 0;
for(int i = 0; i < length; ++i)
{
if(numbers[i] == result)
times++;
}
if(times * 2 <= length)
{
g_bInputInvalid = true;
result = 0;
}
return result;
}
文章部分出自博主何海涛