本文节选自:http://blog.csdn.net/v_july_v/article/details/6890054
加强版水王:找出出现次数刚好是一半的数字
1.用了两个变量来记录水王。
#include<iostream>
using namespace std;
int Find(int* a, int N)
{
int candidate1,candidate2;
int nTimes1, nTimes2, i;
for(i = nTimes1 = nTimes2 =0; i < N; i++)
{
if(nTimes1 == 0)
{
candidate1 = a[i], nTimes1 = 1;
}
else if(nTimes2 == 0 && candidate1 != a[i])
//注意:这里的判断条件加上第二个变量是否等于第一个变量的判断
{
candidate2 = a[i], nTimes2 = 1;
}
else
{
if(candidate1 == a[i])
nTimes1++;
else if(candidate2 == a[i])
nTimes2++;
else
{
nTimes1--;
nTimes2--;
}
}
}
return nTimes1>nTimes2?candidate1:candidate2;
}
int main()
{
int a[4]={0,1,2,1};
cout<<Find(a,4)<<endl;
// int a[6]={1,0,2,1,2,1};
// cout<<Find(a,6)<<endl;
}
2.总数必定是偶数,同时删除不同数字,最后剩余的两个数字必有其一为水王,只需简单判断一下即可。
int Find(int* a, int N) //a代表数组,N代表数组长度
{
int candidate;
int nTimes, i;
for(i = nTimes = 0; i < N; i++)
{
if(nTimes == 0)
{
candidate = a[i], nTimes = 1;
}
else
{
if(candidate == a[i])
nTimes++;
else
nTimes--;
}
}
int cTimes = 0;
int candidate2 = a[N-1];
for(i = 0; i < N; i ++)
{
if(a[i] == candidate)
{
cTimes++;
}
}
return cTimes == N/2 ? candidate : candidate2;
}