思路:
二分查找的思路是先猜一个数(有效范围 [left..right] 里位于中间的数 mid),然后统计原始数组中 小于等于 mid 的元素的个数 cnt。
如果 cnt 严格大于 mid。根据抽屉原理,重复元素就在区间 [left..mid] 里;
否则,重复元素就在区间 [mid + 1..right] 里。
注意:
题目中说长度为 n + 1
的数组,数值在 1
到 n
之间。因此长度为 len
,数值在 1
到 len - 1
之间。left=1是因为没有用数组的下标进行查找,直接比较数字大小。
public int findDuplicate(int[] nums){
int left=1;
int right=nums.length-1;
while(left<right){
int mid=left+(right-left)/2;
int count=0;
for(int num:nums){
if(num<=mid){
count++;
}
}
if(count<=mid){
left=mid+1;
}
else{
right=mid;
}
}
return left;
}