Programe_Of_Beauty:2.3 寻找发帖“水王”及扩展问题
2011-06-06 15:44 x_feng 阅读(256) 评论(0) 收藏 举报问题:其实问题可以简单的说:有一个数组,数组中的某个元素出现的次数超过N/2。问有没有很好的方法快速找到这个元素。
解析:如:char ID[5] = { ‘a’,‘b’,‘a’,‘c’,‘a’};a的出现次数为3。一个很高效的方法就是:当两个元素不相同时就把这两个元素都删除,这样最后剩下的就是要找的元素,当然不一定是真的删除。
#ifndef _2_3_TANGO_H_
#define _2_3_TANGO_H_
//2.3寻找发帖水王 p129
#include <iostream>
//本题目的含义是,在一个序列中寻找出现次数最多的id,如a,a,b,c,a,b,a,a 当然a出现次数最多
//如果遍历的话要n^2的复杂度,如果排序的话也要n*logn的时间,如何在n的时间内找到呢?
using namespace std;
void TangoFind(char* arrID, int size)
{
char candidate;
int nTimes = 0;//元素出现次数
for (int i = 0; i < size; ++i)//如果有两个元素不同,则删除这两个元素,当然不是真的删除
{
if (0 == nTimes)//记录某个元素和其它元素不同的次数
{
candidate = arrID[i];//如果nTimes为0,则表明 在这之前的元素 如a,b,b,c有偶数个不同对 出现,当然都删除
}
else
{
if (candidate == arrID[i])//如果这个元素又出现 则加1
{
nTimes++;
}
else//如果这个元素没有出现,就是当前的与它不同 就--
{
nTimes--;
}
}
}
cout<<"candidate="<<candidate<<endl;
}
#endif//_2_3_TANGO_H_
扩展问题:着Tango的发展,管理员发现,“超级水王”没有了。统计结果表明,有3个发帖很多的ID,他们的发帖数目都超 过了帖子总数目N的1/4。你能从发帖ID列表中快速找出他们的ID吗?
关键想法是:先记录3个不的元素,然后再计算下一个元素是否出现在已经记录的3个元素中,如果有则相应的加1,如果没有则3个元素都减1.
int a[] = {1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,5,6,7,9};
int aTimes=0;
int bTimes=0;
int cTimes=0;
int aCur=0;
int bCur=0;
int cCur=0;
//int cur=0;
for (int i = 0; i < 20; i++)
{
if (aTimes ==0)
{
aCur = a[i];
aTimes = 1;
}
else
{
if (aCur == a[i])
{
aTimes++;
}
else
{
if (bTimes == 0)
{
bCur = a[i];
bTimes = 1;
}
else
{
if (bCur == a[i])
{
bTimes++;
}
else
{
if (cTimes == 0)
{
cCur = a[i];
cTimes = 1;
}
else
{
if (cCur == a[i])
{
cTimes++;
}
else
{
aTimes--;
bTimes--;
cTimes--;
}
}
}
}
}
}
}
cout<<aCur<<" "<<bCur<<" "<<cCur<<endl;
}
结果为:1 2 3。当然我们发现,有3个元素都超过了总数的1/4,那么这3个元素的总和超过了3/4,我们可以用一个桶来操作,桶的大小为(1/4)*N +3。或者用map关联容器也可以。
浙公网安备 33010602011771号