算法--找出数组中出现次数超过一半的数

 

作者:陈太汉

算法--找出数组中出现次数超过一半的数
          每当我看到经典的算法题,就怀念高中,感觉很多算法题就是高中的题目,谁叫哥只读了个专科,高数基本相当没学。
          有空要看看高数啊,想当年数学那是相当的......

  方法一
          第一个想到的方法是见一个二维数组,一维存数组中的数据,二维存这个数出现的次数。出现次数最多的那个数就是要找的那个数
          由于某个数出现的次数超过数组长度的一半,所以二维数组的长度只需要这个数组的一半。代码实现如下,
          当然这个方法很糟糕,时间复杂度和空间复杂度都比较大,想练手的我还是写了一下。

	void Search(int A[],int len,int& theOne)
	{
		if(NULL==A || len<=0)
		{
			return ;
		}

		int (*B)[2]=new int[len/2][2];
		B[0][0]=A[0];
		B[0][1]=1;

		int t=0;
		bool notExist=true;
		for(int i=1;i<len;++i)
		{
			for(int j=0;j<t;++j)
			{
				if(A[i]==B[j][0])
				{
					B[j][1]++;
					notExist=false;
					break;
				}
			}
			if(notExist)
			{
				B[t++][0]=A[i];
			}
		}
		
		int max=1;
		int k=0;
		for(int i=0;i<len/2;++i)
		{
			if(B[i][1]>max)
			{
				max=B[i][1];
				k=i;
			}
		}
		
		theOne=B[k][0];
	}
 

方法二
         将数组排序,最中间的那个数就是您要找的数。
         如果出现最多的那个数是最小的,那么1至(n+1)/2都是那个数
         如果出现最多的那个数是最大的,那么(n-1)/2至n都是那个数
         如果不是最小也不是最大,当这个数由最小慢慢变成最大的最大的数时,你会发现中间的那个数的值是不变的。
         综上所述,中间的那个数就是你要找的那个数。
         时间复杂度就是你排序用的时间。排序真的不想写了(可以参考《我的另一篇博客》)。大家都知道排序还是相当费时的,当然这个方法还是不太好。

 方法三
        这个方法借用了别人的思路。
        在这里我做一下简单的分析。
        这个算法的时间复杂度是O(n),另外用了两个辅助变量。
        k用于临时存储数组中的数据,j用于存储某个数出现的次数。
        开始时k存储数组中的第一个数,j为0,如果数组出现的数于k相等,则j加1,否则就减1,如果j为0,就把当前数组中的数赋给k
        因为指定的数出现的次数大于数组长度的一半,所有j++与j--相抵消之后,最后j的值是大于等于1的,k中存的那个数就是出现最多的那个数。

      下面这个算法只适合数组中数组中某个数的出现次数超过数组长度一半的数组,符合题意。

int Search(int A[],int len)
	{
		if(NULL==A || len<=0)
		{
			return -1;
		}

		int k, j=0;
		for(int i=0;i<len;++i)
		{
			if(j==0)
			{
				k=A[i];
			}
			if(k==A[i])
			{
				++j;//有人说++j比j++有先天的优势,不知你是否听说,如果你也听说,有没有想过More Effective C++(C++程序员必看书籍)
			}else
			{
				--j;
			}
		}

		return k;
	}


 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值