在一個長度爲n+1的數組裏的全部數字都在 1~n 的範圍內,因此數組中至少有一個數字是重複的。請找出數組中任意一個重複的數字,但不能修改輸入的數組。例如,若是輸入長度爲 8 的數組 {2,3,5,4,3,2,6,7},那麼對應的輸出是重複的數字 2 或者 3。java
這道題目能夠把 1~n 數字從中間的數字 m 分爲兩部分,前面一半爲 1~m,後面一半爲 m+1~n。若是 1~m 的數字的數目超過 m,那麼這一半的區間裏必定包含重複的數字;不然,另外一半 m+1~n 的區間裏必定包含重複的數字。數組
以長度爲 8 的數組 {2,3,5,4,3,2,6,7} 爲例分析查找的過程。長度爲 8 因此中間的數字爲 4,把這個數組分爲兩部分,一段是 1~4,另外一部分是 5~7。接下來統計 1~4 這 4 個數字在數組中出現的次數,它們一共出現了 5 次,所以這 4 個數字中必定存在重複的數字。code
接下來把 1~4 的範圍一分爲二,一段是 一、2 兩個數字,另外一段是 三、4 兩個數字。數字 一、2 出現了兩次,所以統計 三、4 出現的次數,它們一共出現了三次,所以存在重複的數字。再分別統計 3 和 4 出現的次數,最終輸出的結果是 3。io
public int solution2(int[] numbers){ if(numbers==null || numbers.length<=0) return -1; int start = 1; int end = numbers.length; while(start<=end){ int mid = (start+end)/2; int count = countRange(numbers,start,mid); if(start==end){ if(count>1) return start; else break; } if(count>(mid-start+1)) end = mid; else start = mid+1; } return -1; } private int countRange(int[] numbers,int start,int end){ int count = 0; for(int i=0;i<numbers.length;i++){ if(numbers[i]>=start && numbers[i]<=end) count++; } return count; }