题目
给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。
假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。
思路1
二分法
计算数组中小于等于mid的值(cnt)有多少个,若cnt<=mid值,则代表重复的值在mid的右侧;若cnt>mid值,则代表重复的值在mid的左侧;
代码1
class Solution {
public int findDuplicate(int[] nums) {
int n = nums.length;
int l = 0;
int r = n - 1;
int ans = 0;
while (l <= r) {
int mid = (l + r) >> 1;
int cnt = 0;
for(int i = 0;i < n;++i) {
if (nums[i] <= mid) {
cnt++;
}
}
if (cnt <= mid) {
l = mid + 1;
} else {
r = mid - 1;
ans = mid;
}
}
return ans;
}
}```
## 思路2
快慢指针
在数组中建立环:即通过数组的值作为索引来指向下一个数组的值;即对于数组[1,2,3,4,5,6,7,3],通过1->2->3->4->5->6->7->3->4->5->6->7->3->4->5->6->7。。。(环为3->4->5->6->7->3)。我们想要找的重复的值就是环的入口3。
首先通过设定快慢指针fast与slow为0。slow每次移动一步(slow=nums[slow]),fast每次移动两步fast=nums[nums[fast]],这样它们会在环中相遇(因为环外不可能相遇,在环中循环时会相遇),记录相遇的位置。
再设置finder=0,使finder和slow同时移动,相遇时即为重复的值,即环的入口。[详细原因见链接内容。](https://leetcode-cn.com/problems/find-the-duplicate-number/solution/kuai-man-zhi-zhen-de-jie-shi-cong-damien_undoxie-d/)
## 代码2
```java
class Solution {
public int findDuplicate(int[] nums) {
int slow = 0;
int fast = 0;
do {
slow = nums[slow];
fast = nums[nums[fast]];
} while (slow != fast);
int finder = 0;
do {
finder = nums[finder];
slow = nums[slow];
} while (finder != slow);
return slow;
}
}