您的位置:首页 > 其它

找出数组中出现次数超过一半的元素

2015-12-22 17:02 471 查看
参考地址:http://www.cnblogs.com/DayByDay/p/3871834.html?utm_source=tuicool&utm_medium=referral

题目:找出数组中出现次数超过一半的元素(前提是该元素一定存在)

解法1:每次删除数组中两个不同的元素,删除后,要查找的那个元素的个数仍然超过删除后的元素总数的一半

解法2:如果数据量小,可以对数组进行排序,那么数组中间的数就是出现次数超过一半的数

#include <stdio.h>

int half_number(int a[], int n)
{
if( a == NULL || n <= 0 )
return -1;

int i, candidate;
int times = 0;
for( i=0; i<n; i++ )
{
if( times == 0 )
{
candidate = a[i];
times = 1;
}
else if( a[i] == candidate )
++times;
else
--times;
}
return candidate;
}

int main(void)
{
int a[] = {1,2,3,2,2,2,5,4,2};

int result = half_number(a, 9);
if( result != -1 )
printf("%d\n", result);
else
printf("Error.\n");

return 0;
}


坑!坑!坑!(腾讯挖的):

春节期间小明使用微信收到很多个红包,非常开心。在查看领取红包记录时发现,某个红包金额出现的次数超过了红包总数的一半。请帮小明找到该红包金额。写出具体算法思路和代码实现,要求算法尽可能高效。

给定一个红包的金额数组gifts及它的大小n,请返回所求红包的金额。

本题的测试案例上包括0的情况,即红包中没有出现相同金额次数超过红包一半的,那此种情况应该返回0

class Gift {
public:
int getValue(vector<int> gifts, int n) {
// write code here
// write code here
int nRet;
int nCnt = 0;
for(int i = 0; i < n; ++i){
if(nCnt == 0){
nRet = gifts[i];
nCnt = 1;
}
else if(nRet == gifts[i]){
++nCnt;
}
else{
--nCnt;
}
}
      //最后要做个验证
nCnt = 0;
int nLeft = n;
for(int i = 0; i < n; ++i){
if(gifts[i] == nRet)
++nCnt;
if(nCnt + nLeft < n/2)
return 0;
if(nCnt > n/2)
return nRet;

--nLeft;
}
return 0;
}
};


该题的扩展:数组中有3个元素出现的次数都超过数组元素总数N的1/4, 找出这三个元素

解法:同上,但是每次删除4个互不相同的元素,处理上比上面的稍微麻烦

#include <stdio.h>

void find(int a[], int n)
{
if( a==NULL || n<=3 )
{
printf("Error.\n");
return ;
}

int i,j;
int times[3] = {0,0,0}; // 3个candidate的计数
int candidate[3] = {-1,-1,-1}; // 假设元素不可能是-1

for( i=0; i<n; i++ )
{
if( times[0] == 0 && a[i] != candidate[1] && a[i] != candidate[2] ) // 第1个candidate目前空缺, 且当前元素a[i]不等于其他两个candidate时, 将该元                                                素作为新的candidate
{
candidate[0] = a[i];
times[0] = 1;
}
if( times[1] == 0 && a[i] != candidate[0] && a[i] != candidate[2] )
{
candidate[1] = a[i];
times[1] = 1;
}
if( times[2] == 0 && a[i] != candidate[1] && a[i] != candidate[0] )
{
candidate[2] = a[i];
times[2] = 1;
}
else if( a[i] == candidate[0] )
{
++times[0];
}
else if( a[i] == candidate[1] )
{
++times[1];
}
else if( a[i] == candidate[2] )
{
++times[2];
}
else // 删除4个各不相同的数组元素, 删除后
{
--times[0];
--times[1];
--times[2];
}
}
printf("%d %d %d\n",candidate[0],candidate[1],candidate[2]);
}

int main(void)
{
int a[] = {5,1,1,3,8,1,3,1,4,1,7,1,2,9,2,3,2,3,2,3,2,3,2};
find(a, 23);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: