問題說明:
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲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>