找出数组中出现的次数超过数组长度的一半

问题说明:

数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。

方法1:

如果在一个数组中有一个数字出现的次数超过整个数组长度的一半,那么将该数组排序后,位于中间位置的数字一定是该数字。我们可以给数组进行排列,取出中间值,再拍段该数组的中间值出现次数是否超过该数组总数目的半数。这样效率方面并不是很高,借助于快速排序的思想,对该数组进行一次快速排序,以数组最后一个数字为比较校准,小于该数字的放到其前面,大于该数字的放到其后面。最后返回该数字在数组中所处的位置。如果该数字位于数组的中间,那该数组便可能是这个数组中出现次数超过半数的数字(在该数组中进行该数字个数的查询,判断是否超过半数)。如果返回的数字位置不位于数组中间,则再次进行快速查询。

<span style="font-size:18px;"><span style="white-space:pre">	</span>public static int findMoreThanHalf(int[] arr){
		if(arr==null){
			return -1;
		}
		int len=arr.length;
		int begin=0;
		int end=len-1;
		if(len==0){
			return -1;
		}
		if(len==1){
			return arr[0];
		}
		int middle=len/2;
		int index=per(arr,begin,end);
		while(index!=middle){
			if(index>middle){
				end=index-1;
				index=per(arr,begin,end);
			}else{
				begin=index+1;
				index=per(arr,begin,end);
			}
		}
		int result=arr[index];
		if(!isMoreThanHalf(arr,result)){
			result=-1;
		}
		return result;
	}
	/**
	 * 判断该数组的中间数的个数是不是超过了数组的一般数
	 * @param arr
	 * @param temp
	 * @return
	 */
	public static boolean isMoreThanHalf(int[] arr,int temp ){
		int num=0;
		int middle=arr.length/2;
		for(int i=0;i<arr.length;i++){
			if(arr[i]==temp){
				num++;
			}
		}
		if(num>middle){
			return true;
		}
		return false;
	}
	/**
	 * 快速排序的一次
	 * 以该数组最后一个个值做为标准,比它大的排前面,
	 * 小的排后面
	 * @param arr
	 * @param begin
	 * @param end
	 * @return
	 */
	public static int per(int[] arr,int begin,int end){
		int small=begin-1;
		int len=arr.length;
		if(len==0 || begin>end){
			return -1;
		}
		for(int i=begin;i<end;i++){
			if(arr[i]<arr[end]){
				small++;
				if(small!=i){
					swap(arr,i,small);
				}
			}
		}
		small++;
		if(small!=end){
			swap(arr,small,end);
		}
		return small;
	}
	
	/**
	 * 交换数组指定两位置的值
	 * @param arr
	 * @param fir
	 * @param sec
	 */
	public static void swap(int[] arr,int fir,int sec){
		int temp=arr[fir];
		arr[fir]=arr[sec];
		arr[sec]=temp;
	}</span>

方法2:

<span style="font-size:18px;">/**
	 * 既然是查找一个在数组中重复多余一半的数字,则
	 * 如果计算其个数,一定大于数组中其他数字所有的数目。
	 * 策略:一个数字代替当前数字,一个代表当前数字的个数:
	 * 如果重复则加1,如果不同,则减1;如果num变为0,则把当前数字指向本数字
	 * @param arr
	 * @return
	 */
	public static int isMoreThanHalf(int[] arr){
		if(arr==null){
			return 0;
		}
		int len=arr.length;
		if(len==0){
			return 0;
		}
		int num=1;
		int temp=arr[0];
		for(int i=1;i<len;i++){
			if(arr[i]==temp){
				num++;
			}else{
				num--;
				if(num==0){
					temp=arr[i];
					num++;
				}
			}
		}
		if(num>len/2){
			return temp;
		}
		return 0;
	}</span>


  


发布了17 篇原创文章 · 获赞 1 · 访问量 7853
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章