面试题29数组中出现次数超过一半的数字

面试题29数组中出现次数超过一半的数字

思路:最直观的思路就是对数组进行排序然后取中位数。时间复杂度取决于排序算法。或用Partition()函数找一个枢纽元素将数组分为两部分一部分比枢纽元素小,另一部分比枢纽元素大且枢纽元素的位置要在数组的中位数。

新颖的想法:利用数组的特点,顺序遍历数组的时候保存两个值一个数组中的数字一个是该数字出现的次数若数字相同则次数加1 数字不同则次数减一

注意点:函数的入参检查以及是否有元素出现次数超过数组元素的一半。

函数接口:bool CheckMoreThanHalf(int *a,int length,int value);

int MoreThanHalf(int *a,int length);


#include<iostream>
#include<cstdlib>
#include<cstdio>
using namespace std;
//面试题29数组中出现次数超过一半的数字 :思路 :最直观的思路就是对数组进行排序然后取中位数。时间复杂度取决于排序算法。或用Partition()函数找一个枢纽元素将数组分为两部分一部分比枢纽元素小,另一部分比枢纽元素大且枢纽元素的位置要在数组的中位数。
//创新的想法:利用数组的特点,顺序遍历数组的时候保存两个值一个数组中的数字一个是该数字出现的次数若数字相同则次数加1 数字不同则次数减一
//注意点:函数的入参检查以及是否有元素出现次数超过数组元素的一半。
bool InvalidInput=false;
bool CheckMoreThanHalf(int *a,int length,int value)//检查value 在数组中有没有出现一半;
{
	int count=0;
	for(int i=0;i<length;i++)
	{
	     if(a[i]==value)
		 {
		     count++;
		 }
	}
	if(count*2<=length)
	{
	   InvalidInput=true;
	   return false;
	}
	return true;
}

//比较新颖的解法
int MoreThanHalfNumber2(int *a,int length)
{
    if(a==NULL||length<=0)
	{
	    InvalidInput=true;
		return -1;
	}
	int result=a[0];
	int count=1;//出现的次数
	for(int i=1;i<length;i++)
	{
	    if(count==0)
		{
		    result=a[i];
			count=1;
		}
		else if(a[i]==result)
		{
		    count++;
		}
		else
		{
		    count--;
		}

	}
	if(!CheckMoreThanHalf(a,length,result))
	{
		InvalidInput=true;
	    return -1;
	}
	return result;
	
}
int Partition(int *a ,int start,int end)
{
      int i=start,j=end;
	  int key=a[i];
	  while(i<j)
	  {
	      while(i<j&&a[j]>=key)
		  {
		       j--;
		  }
		  if(i<j)
		  {
		      a[i]=a[j];
			  i++;
		  }
		  while(i<j&&a[i]<=key)
		  {
		       i++;
		  }
		  if(i<j)
		  {
		      a[j]=a[i];
			  j--;
		  }
	  }
	  a[i]=a[j];
	  return i;
}
//方法一  Partition() 方法
int MoreThanHalfNumber(int *a,int length)
{
    if(a==NULL||length<=0)
	{
	    InvalidInput=true;
		return -1;
	}
	int start=0, end=length-1;
	int index=Partition(a,start,end);
	int midIndex=length>>1;
	while(index!=midIndex)
	{
	    if(index<midIndex)
		{
			  start=index+1;
		     index=Partition(a,start,end);
		}
		else if(index>midIndex)
		{
		    end=index-1;
			index=Partition(a,start,end);
		}
	}
	if(!CheckMoreThanHalf(a,length,a[index]))
	{
		InvalidInput=true;
	    return -1;
	}
	return a[index];
}

int main()
{
	int a[]={1,2,3,2,2,2,5,4,2};
	int length=sizeof(a)/sizeof(a[0]);
	int result1=MoreThanHalfNumber(a,length);
	if(!InvalidInput)
	{
	    cout<<"数组中出现一半的数字为:"<<result1<<endl;
	}

	int result2=MoreThanHalfNumber2(a,length);
	if(!InvalidInput)
	{
	    cout<<"数组中出现一半的数字为:"<<result2<<endl;
	}
   return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值