劍指offer 29題 【時間效率】數組中出現次數超過一半的數字

題目描述

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

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章