數組中出現次數超過一半的數字


題目描述
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。例如輸入一個長度為9的數組{1,2,3,2,2,2,5,4,2}。由於數字2在數組中出現了5次,超過數組長度的一半,因此輸出2。如果不存在則輸出0。

方法一 ---- 基於隨機快排
如果數組中存在一個數字的出現次數大於數組長度一半,那么將這個數組排序后位於該數組的中位數就是這個數字。
在隨機快速排序中,現在數組中隨機選擇一個數字,然后調整數組中的數字的順序,使得比選中的數字小的的數字都在它的左邊,比他大的數字都在其右邊。如果這個選中的數字的下標剛好是n/2,那么這個數字就是數組的中位數;如果這個下標大於n/2,那么中位數應該在它的左邊,我們可以接着在它左邊部分的數組中查找;如果這個下標小於n/2,那么表示中位數在它的右邊,在右邊的數組中查找。是一個典型的遞歸過程。

	/** * 利用Partition函數的時間復雜度為O(n)的算法 * @param array * @return */
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length == 0) {
        	return 0;
        }
        if(array.length == 1) {
        	return array[0];
        }
        
        int middle = array.length / 2;
        int start = 0;
        int end = array.length - 1;
        
        int index = Partition(array, start, end);
        while(index != middle) {
        	if(index > middle) {
        		end = index - 1;
        		index = Partition(array, start, end);
        	}
        	else {
        		start = index + 1;
        		index = Partition(array, start, end);
        	}
        }
        
        int result = array[middle];
        if(!CheckMoreThanHalf(array, result)) {
        	result = 0;
        }
        return result;
    }
    
    public boolean CheckMoreThanHalf(int[] elem, int result) {
    	int times = 0;
    	boolean isMoreThanHalf = true;
    	for (int i = 0; i < elem.length; i++) {
			if(elem[i] == result) {
				++times;
			}
		}
    	
    	if(times * 2 <= elem.length) {
    		isMoreThanHalf = false;
    	}
    	
    	return isMoreThanHalf;
    }
    
    public int Partition(int[] elem, int low, int high) {
    	int pivotkey = elem[low];
    	while(low < high) {
    		while((low < high) && elem[high] > pivotkey) {
    			high--;
    		}
    		swap(elem, low, high);
    		while((low < high) && elem[low] <= pivotkey) {
    			low ++;
    		}
    		swap(elem, low, high);
    		
    	}
    	return low;
    }
    
    
    
    public void swap(int[] elem, int i, int j) {
    	int temp = elem[i];
    	elem[i] = elem[j];
    	elem[j] = temp;
    }

方法二 ---- 根據數組特點
如果有一個數字在數組中出現次數大於數組的一半,那么也就是說他出現的次數比其他數字出現次數和還要多。我們可以設置兩個變量,一個保存數組中的一個數字,另外一個保存次數,遍歷數組,當遍歷到下一個數字時,如果下一個數字和之前保存的數字相同,次數加1;如果不同次數減1;如果次數為0,那么我們需要保存下一個數字,並將次數還原為1。

    /** * 根據數組特點找出時間復雜度為O(n)的算法 * @param args */
    
    public int MoreThanHalfNum_Solution_2(int [] array) {
    	if(array == null || array.length == 0) {
    		return 0;
    	}
    	
    	if(array.length == 1) {
    		return array[0];
    	}
    	
    	int tempNumber = array[0];
    	int times = 1;
    	
    	for (int i = 1; i < array.length; i++) {
    		if(tempNumber == array[i]) {
    			times++;
    		}
    		else {
    			
    			times--;
        		if(times == 0) {
        			tempNumber = array[i];
        			times = 1;
        		}

    		}
		}
        if(!CheckMoreThanHalf(array, tempNumber)) {
        	tempNumber = 0;
        }
        return tempNumber;
    	
    }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM