题目:
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.
解决方法一:Runtime: 5 ms 改变了数组,不正确
public class Solution {
public int findDuplicate(int[] nums) {
if(null==nums||nums.length<=0) return -1;
Arrays.sort(nums);
for(int i=0;i<nums.length-1;i++){
if(nums[i]==nums[i+1]) return nums[i];
}
return -1;
}
}
解决方法二: Runtime: 5 ms 还是改变了数组,不正确
public class Solution {
public int findDuplicate(int[] nums) {
if(null==nums||nums.length<=0) return -1;
for(int i=0;i<nums.length;i++){
if(nums[Math.abs(nums[i])-1]>0) nums[Math.abs(nums[i])-1]=-nums[Math.abs(nums[i])-1];
else if(nums[Math.abs(nums[i])-1]<0) return Math.abs(nums[i]);
}
return -1;
}
}
解决方法三: 把问题转换为找环起点问题 Runtime: 1 ms
public class Solution {
public int findDuplicate(int[] nums) {
if(null==nums||nums.length<=0) return -1;
int slow =0;
int fast =0;
do{
slow=nums[slow];
fast=nums[nums[fast]];
}while(slow!=fast);
fast=0;
while(fast!=slow){
fast=nums[fast];
slow=nums[slow];
}
return slow;
}
}
参考: