思路:要求比较严苛
首先先介绍二分法,一种时间复杂度是O(nlogn),空间复杂度是O(1)的做法。
class Solution {
public int findDuplicate(int[] nums) {
int left = 1,right = nums.length - 1;
while(left < right){
int mid = left + right >> 1;
//System.out.println("left:"+left+", right:"+right);
int count = countsmaller(nums,mid);
if(count > mid){
right = mid;
//System.out.println("right应该更改为:"+right);
}else{
left = mid + 1;
//System.out.println("left应该更改为:"+left);
}
}
return left;
}
public int countsmaller(int[] nums,int target){
int count = 0;
for(int i = 0;i < nums.length;i++){
if(nums[i] <= target){
count++;
}
}
return count;
}
}
还有一种是比较技巧性的做法,时间复杂度是O(N),空间复杂度是O(1)
class Solution {
public int findDuplicate(int[] nums) {
int slow = nums[0], fast = nums[nums[0]];
while(fast != slow){
fast = nums[nums[fast]];//快指针走两步
slow = nums[slow];//慢指针走1步
}
fast = 0;
while(fast != slow){
fast = nums[fast];//同时走
slow = nums[slow];
}
return fast;
}
}