- 暴力:两层for循环
快慢指针
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0;
int fast = 0;
slow = nums[slow];
fast = nums[nums[fast]];
// fast 向后移动两步,slow 移动一步,找到相遇节点
//这个移动不明白是咋回事
while(slow != fast){//即
slow = nums[slow];
fast = nums[nums[fast]];
}
//找入口节点
int pre1 = 0;
int pre2 = slow;
while(pre1 != pre2){
pre1 = nums[pre1];
pre2 = nums[pre2];
}
return pre1;
}
}
二分查找
class Solution {
public int findDuplicate(int[] nums) {
int n = nums.length;
int l = 1, r = n - 1, ans = -1;
while (l <= r) {
//不断削减数组,改变mid的值
int mid = (l + r) >> 1;
int cnt = 0;
//统计数组中小于mid的数量
for (int i = 0; i < n; ++i) {
if (nums[i] <= mid) {
cnt++;
}
}
//数量比mid小,那么前边的都符合,于是改变left的值
if (cnt <= mid) {
l = mid + 1;
//数量比mid多,改变右侧right的值,顺便把当前的mid赋给ans
} else {
r = mid - 1;
ans = mid;
}
}
return ans;
}
}