Leetcode169. 9oj编号1370. 剑指29. 编程之美的发帖水王。
普通方法:排序,然后找位于中间位置的数。
进阶方法:Hash映射次数。
高级方法:次数擂台PK法。
高级方法考虑到题目中数组的一个特性:数组中有个数字出现的次数超过了数组长度的一半。也就是说,有个数字出现的次数比其他所有数字出现次数的和还要多。因此我们可以考虑在遍历数组的时候保存两个值:一个是数组中的一个数字boss,一个是次数times。
当我们遍历的时候:
如果数字i和我们之前保存的数字boss相同,则次数times加1。
如果数字i和我们之前保存的数字boss不同,则次数times减1。
如果次数times为零,我们需要保存数字boss=i,并把次数设为1。
由于我们要找的数字出现的次数比其他所有数字出现的次数之和还要多,那么要找的数字肯定是最后留下的数字。(水王一定会把其他人PK下去,而别人无法PK掉水王)。
高级方法的代码:
#include <stdio.h>
int Findyou(int a[], int n)
{
int i, times, boss;
boss = a[0];
times = 1;
for(i=1;i<n;i++)
{
if(a[i] == boss)
times++;
else
times--;
if(times == 0)
{
boss = a[i];
times = 1;
}
}
times = 0;
for(i=0;i<n;i++)
if(a[i] == boss)
times++;
if(times > n/2)
return boss;
else
return -1;
}
int main()
{
int i,n;
int a[100000];
int mid,left,right;
while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d",&a[i]);
printf("%d\n", Findyou(a, n));
}
return 1;
}
也可以用栈来解决。
先把第一个数入栈。
顺序遍历原序列中的数:如果它和当前栈顶相同或者栈为空,则入栈;如果它和当前栈顶不同,则不入栈,且要把当前栈顶出栈。
最终栈中剩下的数就是所找的数。