善于利用快慢指针
这道题的难点不在于代码,而是在于理解原因
a = nums[a]理解成一步
自然 a = nums[nums[a]]就为两步,这就是快慢指针了
只要数组的值小于数组的长度,就总有一天会形成一个环
现在要找到重复数,其实就是找到,那个重复点
现在我们使用快慢指针,就能找到相交点
由于是快慢指针,所以“从起点绕一圈之后到达相交点的距离”是“从起点到相交点的距离”的两倍
自然,“从起点到相交点的距离” = “从相交点绕一圈到相交点的距离”
而从重复点到相交点的那一段是重复的,
所以“从起点到重复点的距离” = “从相交点绕一圈到重复点的距离”
我们就用相同的频率从起点和相交点出发,就能找到重复点
public int findDuplicate(int[] nums) {
int fast = 0, slow = 0;
while(true) {
fast = nums[nums[fast]];
slow = nums[slow];
//找到相交点
if(slow == fast) {
fast = 0;
//找到重复点
while(nums[slow] != nums[fast]) {
fast = nums[fast];
slow = nums[slow];
}
return nums[slow];
}
}
}
来源:https://blog.csdn.net/qq_33321609/article/details/98961726