# 面试题: 数组中出现超过一半 的数字
/*
题目: 数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。 例如输入一个长度为9 的数组{1,2,
3,2,2,2,5,4,2}。 由于数字2 在这个数组中出现了 5次,超过了数组长度的一般,因此输出 5。
*/
# 题目分析:
看到这道题,相信大多数人和我一样想到的是,将数组中每一个元素出现的次数保存在一个数组里
面, 然后找出出现次数超过一半的元素; 那么这样是不是过于复杂,时间复杂度为 O(nlogn). 这样是最直观的算
法,但往往不是面试官想要的答案!
如果我们仔细分析这道题不难发现,如果考虑这个数组的特性,那么这道题就会简单了许多! 找出数组中出现次
数超过一半的元素,如果我们将数组进行排序,那么,排序之后位于数组中间的元素一定是那个出现次数超过一半的
数字; 这个算法里面有快速排序的影子,因为我们为你调用了 是先快速排序时的 Partition 函数;
当我们排序好数组之后;返回的Partition函数 选中数字的下标大于 n/2 那么中位数应该在他左边, 如果小于 n/2
那么中位数应该在它的右边, 如果等于n/2 那么它就是中位数。
# 代码实现:
bool g_bInputInvalib = false;
int Partition(int data[], int length, int start, int end)
{
int index;
int Small;
if(data == NULL || length <= 0 || start < 0 || end >= length)
return ;
index = RandomInRange(start, end);
//RandomInRange 是随机产生start和end中间的一个数;
Swap(&data[index], &data[end]);
//Swap 是交换两个数的函数;
Small = start -1;
for(index = start; index < end; ++index)
{
if(data[index] < data[end])
{
++Small;
if(Small != index)
Swap(&data[index], &data[Small]);
}
}
++Small;
Swap(&data[Small], &data[end]);
return Small;
}
/*
CheckInvalibdaArry 函数判断输入的数组是不是无效的;
*/
bool CheckInvalibdaArry(int *number, int length)
{
g_bInputInvalib = false;
if(number == NULL || length <= 0)
g_bInputInvalib = true
return g_bInputInvalib;
}
/*
CheckMoreThanHalf 函数用来判断找出的出现频率最高的数是不是出现次数超过了数组长度的一半;
*/
bool CheckMoreThanHalf(int *numbers, int length, int number)
{
int i = 0;
int times = 0;
bool isMoreThanHalf = true;
for(i = 0; i <= length; ++i)
{
if(numbers[i] == number)
times++;
}
bool isMoreThanHalf = true;
if(times *2 <= length)
{
g_bInputInvalib = true;
isMoreThanHalf = false;
}
return isMoreThanHalf;
}
int MoreThanHalfNum(int * numbers, int length)
{
int result = 0;
int middle = length >> 1;
int start = 0;
int end = length - 1;
int index = Partition(numbers,length,start,end);
if(CheckInvalibdaArry(numbers,length))
return 0;
while(index != middle)
{
if(index > middle)
{
end = index - 1;
index = Partition(numbers, length, start, end);
}
else
{
start = index - 1;
index = Partition(numbers, length, start, end);
}
}
result = numbers[middle];
if(!CheckMoreThanHalf(numbers, length,result))
result = 0;
return result;
}
over!