題目描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度爲9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。
寫一個魯棒的代碼還是不容易的...
思路:
1.不斷地利用partition函數進行分割,結束條件爲partition返回的index 是數組長度的一半。因爲我們尋找的這個數字超過一半,所以中間的這個數就是要尋找的。
2.假設這個數字是第一個,並計數1。那麼遍歷數組,如果遇到相同的數字,則計數加一,否則減一,當計數小於0時把當前數字假設爲我們所求的數,並重新計數。最後檢查這個數字是否是超過一半的。
代碼一:public class Title29 {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length == 0)
return 0;
int begin = 0,end = array.length-1,index = -1;;
int mid = (begin + end) >>> 1;
while(index != mid){
index = partition(array,begin,end);
if(index > mid){
end = index - 1;
}else{
begin = index + 1;
}
}
if(checkHalf(array, array[index]))
return array[index];
return 0;
}
public int partition(int[] array,int begin,int end){
int pos = selectNumber(array,begin,end);
swap(array,pos,end);
int small = begin -1;
for(int i=begin;i<end;i++){
if(array[i] < array[end]){
++small;
if(i != small){
swap(array,i,small);
}
}
}
++small;
swap(array,small,end);
return small;
}
// 三數取中
public int selectNumber(int[] array,int begin,int end){
if(end-begin>1){
int mid = (end+begin) >> 1;
int max = begin;
// 獲取最大的位置
if(array[max] < array[mid])
max = mid;
if(array[max] < array[end])
max = end;
//
if(max == begin){
return array[mid] > array[end] ? mid : end;
}else if(max == mid){
return array[begin] > array[end] ? begin : end;
}else{
return array[begin] > array[mid] ? begin : mid;
}
}
return begin;
}
public void swap(int[] array,int posA,int posB){
int temp = array[posA];
array[posA] = array[posB];
array[posB] = temp;
}
public boolean checkHalf(int[] array,int num){
int count = 0;
for(int i=0;i<array.length;i++){
if(array[i] == num)
count ++;
}
if(count > (array.length >>>1))
return true;
return false;
}
public static void main(String[] args) {
//int[] a = {1,2,3,2,2,2,5,4,2};
// new Title29().MoreThanHalfNum_Solution(a);
//int[] b = {1,2,3,2,4,2,5,2,3};
//new Title29().MoreThanHalfNum_Solution(b);
int[] c = {2,2,2,2,2,1,3,4,5};
System.out.println(new Title29().MoreThanHalfNum_Solution(c));
}
}
代碼二:public class Title29 {
public int MoreThanHalfNum_Solution(int [] array) {
if(array == null || array.length == 0)
return 0;
int num=array[0],count = 0;
for(int i=1;i<array.length;i++){
if(array[i] == num)
count++;
else{
count--;
if(count<0){
num = array[i];
count = 0;
}
}
}
if(checkHalf(array, num))
return num;
return 0;
}
public boolean checkHalf(int[] array,int num){
int count = 0;
for(int i=0;i<array.length;i++){
if(array[i] == num)
count ++;
}
if(count > (array.length >>>1))
return true;
return false;
}
}