题目描述
在一个长为n+1的数组里的所有数字都在1~n的范围内,所以数组中至少有一个数字是重复的,请找出数组中任意一个重复的数字,但不能修改输入的数组。
示例
输入: {2, 3, 5, 4, 3, 2, 6, 7}
输出: 2或3
解析
我们把从1~n的数字从中间的数字m分为两部分,前面一半为1~m,后面一半为m+1~n,如果从1~m的数字的数目超过m,那么这一半的区间里一定包含重复数字,否则,另一半区间m+1~n一定包含重复的数字。这个过程与二分查找很类似,只是多了一步统计区间里数字的数目。
public int getDuplication(int[] nums) {
int length = nums.length;
int start = 1;
int end = length - 1;
while(start <= end){
int mid = ((end - start) >> 1) + start;
int count = countRange(nums, length, start, mid);
if(end == start){
if(count > 1){
return start;
}else {
break;
}
}
if(count > (mid - start + 1)){
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
public int countRange(int[] nums, int length, int start, int mid){
if(nums == null){
return 0;
}
int count = 0;
for(int i=0; i<length; i++){
if(nums[i] >= start && nums[i] <= mid){
++ count;
}
}
return count;
}