题目:
找出数组中出现次数超过数组长度一半的数。比如给定数组{1, 2, 3, 4, 2, 2,2,6, 2},我们最后要返回的值就是2。
实现思路:
(1)我们要找出现次数超过数组一半的数字,也就是说它出现的次数比其他所有数字出现的次数的和还要多。
(2)因此我们可以考虑用两个变量:一个保存数字,一个保存次数。开始时,保存数组中第一个元素,次数设置为1;
(3)遍历数组:
1)如果下一个数字和当前保存的数字相同,则次数递增1;2)如果下一个数字和当前保存的数字不同,则次数递减1;
3)如果次数为零,我们需要保存下一个数字,并把次数设为1。
4)由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后一次把次数设为1时对应的数字。
5)但是最后还是需要检查一下该数字的出现次数是否超过了数组长度的一半,因为可能数组中并不包含这样的数字。
实现代码:
#include <stdio.h>
#include <stdlib.h>
int MoreThanHalf(int a[], size_t size)
{
int cur = a[0];
int count = 1;
int i = 0;
for (i = 1; i < size; ++i)
{
if (count == 0)
{
cur = a[i];
count++;
}
else
{
if (cur == a[i])
count++;
else
count--;
}
}
return cur;
}
int main()
{
int a[11] = { 1, 2, 4, 5, 4, 2, 2, 2, 6, 2,2 };
int len = sizeof(a)/sizeof(a[0]);
printf("%d\n", MoreThanHalf(a, len));
system("pause");
return 0;
}
上述方法可能比较抽象,其实我们想要实现时间复杂度为O(n),还可以利用“空间换时间”的思想。我们之间介绍过哈希表,我们可以将每个数字出现第一次的下标作为插入位置,将哈希表中对应位置存上它出现的次数,最后找哈希表中值最大的也就是出现次数最多的数就可以了。
或者是,可以先将数组排序,中间元素一定是我们要找的数。