問題
數組中有一個數字出現的次數超過數組長度的一半,請找出這個數字。面試
例如: 輸入一個長度爲7的數組,數組
{1,2,2,2,5,4,2}
因爲數字2在數組中出現了4次,超過數組長度的一半,所以輸出2。若是不存在則輸出0。spa
解答調試
首先說這是一道很經典的面試題,不少互聯網公司都曾經採用過這個題目。code
下面是對該題的分析思路:排序
若是沒有時間複雜度的要求, 咱們能夠對數組進行排序,排序後的數組,那麼咱們只要遍歷一次就能夠統計出每一個數字出現的次數,這樣也就能找出符合要求的數字。按照這個思路的時間複雜度是O(nlogn), 其中排序的時間複雜度是O(nlogn),遍歷的時間複雜度O(n)。字符串
另外一個思路是咱們能夠建立一個哈希表來消除排序的時間。哈希表的鍵值爲數組中的數字,值爲該數字對應的次數。有了這個哈希表以後,咱們只須要遍歷數組中的每一個數字,找到它在哈希表中對應的位置並增長它出現的次數。這種哈希表的方法在數組的全部數字都在一個比較窄的範圍內的時候頗有效。get
最佳思路:數組中有一個數字出現的次數超過數組長度的一半,也就是說它出現的次數比其餘全部數字出現次數的和還要多。
所以咱們能夠考慮在遍歷數組的時候保存兩個值:一個是數組中的一個數字,一個是次數。當咱們遍歷到下一個數字的時候,若是下一個數字和咱們以前保存的數字相同,則次數加1;若是下一個數字和咱們以前保存的數字不一樣,則次數減1。
若是次數爲0,咱們須要保存下一個數字,並把次數置1。由於次數爲0,表示前面是字符串計數抵消爲0。源碼
//Java源碼 public int MoreThanHalfNum_Solution(int [] numbers) { int maxNum = 0; if(numbers.length==0) return maxNum; maxNum = numbers[0]; int numCount = 1; for(int i=1;i<numbers.length-1;i++){ if(numbers[i] == maxNum){ numCount++; }else{ numCount--; if(numCount == 0){ numCount = 1; maxNum = numbers[i]; } } } int total = 0; for (int i = 0; i < numbers.length; i++) { if (numbers[i] == maxNum) total++; } if (total * 2 <= numbers.length) { return 0; } else return maxNum ; }
上述源碼能夠在 這裏 調試io