找出數組中出現的次數超過數組長度的一半

問題說明:

數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章