287. Find the Duplicate Number
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than
O(n2)
. - There is only one duplicate number in the array, but it could be repeated more than once.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
Subscribe to see which companies asked this question.
题目简介:
输入一个数组,数组中元素满足1<=元素<=n。由于数组的长度是n+1,所以至少存在一个出现两次的元素。(题目假定只有一个这样元素)
要求:找出这个元素
限制:
不能修改数组
空间复杂度O(1)
时间复杂度小于O(n^2)
思路简述:
下面的文章分析的挺好,我就直接上连接了:
但是上面文章//映射找环法,我觉得不对(虽然Accept),因为这样的数组中,存在的很多环。。。such as [2 3 4 5 6 7 1 8 8]
代码:
public class Solution {
//不能修改元素,这个方法是修改元素不符合要求
/*
public int findDuplicate(int[] nums) {
for(int i=0;i<nums.length;i++){
if(nums[i] == i+1 || nums[i]==-1){
nums[i] = -1;
}else{
if(nums[nums[i]-1] == -1){
return nums[i];
}else{
int forTemp =i;
int nowTemp =nums[i]-1;
while(nums[nowTemp] != nowTemp+1){
nums[forTemp] = nums[nowTemp];
nums[nowTemp] = -1;
nowTemp = nums[forTemp]-1;
if(nums[nowTemp]==-1){
return nowTemp+1;
}
}
nums[nowTemp] = -1;
}
}
}
//没有用,就是为了编译通过,
return 0;
}
*/
//二分法
/*
public int findDuplicate(int[] nums){
//int min=1,max=nums.length;
int min = 0,max = nums.length -1;
while(min <= max){
int mid= min + (max-min)/2;
int count = 0;
//计算总数组中有多少小于等于中间数
for(int i=0;i<nums.length;i++){
if(nums[i]<=mid){
count++;
}
}
if(count >mid){
max = mid-1;
}else{
min = mid+1;
}
}
return min;
}
*/
//映射找环法
public int findDuplicate(int[] nums){
int slow = 0;
int fast = 0;
do{
slow = nums[slow];
fast = nums[nums[fast]];
}while(slow != fast);
int find = 0;
while(find != slow){
slow = nums[slow];
find = nums[find];
}
return find;
}
}
结果: