寻找主元素

52 阅读2分钟

今天学习了一个算法,题目如下:
【2013 年第 41 题】已知一个整数序列 A=(a0, a1, …, an-1),其中 0≤ai<n(0≤i<n)。若存 在 ap1=ap2=…=apm =x 且 m>n/2(0≤pk<n,1≤k≤m),则称 x 为 A 的主元素。例如 A=(0,5,5,3,5,7,5,5), 则 5 为主元素;又如 A=(0,5,5,3,5,1,5,7),则 A 中没有主元素。假设 A 中的 n 个元素保存在一个一第 2 章 线性表 25 维数组中,请设计一个尽可能高效的算法,找出 A 的主元素。若存在主元素,则输出该元素;否 则输出-1。
这道题目主要的思想就是:主元素的值一定大于数组长度的一半,也就是说,主元素的个数减去数组中非主元素的个数得到的结果一定大于零,可以从这里切入。
下面看代码:

int search(int arr[],int len){
 	//int len=sizeof(arr)/sizeof(arr[0]);
 	int key=arr[0];
 	int count=1;
 	for(int i=1;i<len;i++){
 		if(arr[i]==key)
 		count++;
 		else{
 		if(count>0){
 			count--;
		 }
		 else
		 {
		 	key=arr[i];
		 	count=1;
		 }
	}
	 }
	 if (count>0){
	 	count=0; 
	 	for(int j=0;j<len;j++){
	 		if(arr[j]==key)
	 		count++;
		 }
		 if(count>len/2)
		 return key;
	 }
	 else 
		 return -1;
 }

第二行有一个注释
因为这里计算arr的长度的时候不能用arr.length,只能用sizeof(arr)/sizeof(arr[0]),简单来说,就是我把C和java搞混了。
并且不能在函数体中计算数组长度,因为: 在 C 语言中,数组作为参数传递时会退化为指针,所以sizeof(arr)/sizeof(arr[0])得到的结果永远是4/4=1(32 位系统)或8/4=2(64 位系统),无法正确获取数组长度。
感觉这道算法题思想挺巧妙的,简单分享一下,谢谢大家观看。