思路:
题目要求不能修改数组nums,也就是不能原地修改
并且要求空间复杂度为O(1),表明不能使用哈希表
则此题利于位运算或floy算法
代码:
class Solution {
public int findDuplicate(int[] nums) {
int f=0,s=0;
//第一次循环找到相遇点
while(true){
f=nums[nums[f]];
s=nums[s];
if(f==s){
break;
}
}
//第二次,慢指针再走a步就到环入口处了
f=0;
while(f!=s){
f=nums[f];
s=nums[s];
}
return f;
}
}
分解:
双指针
设置a为起点到环入口的距离,b为环的长度
1)第一次走:找到相遇点,此时slow指针再走a步就到达环的入口了
由于计算得到:f=2nb,s=nb,f=s+kb
2)第二次走,fast指针置为0,此次走到相遇点就是环的入口了
3)之前的循环链表fast走2步的表示为:fast=fast.next.next
此题的数组走2步表示为:fast=nums[nums[fast]]
走1步为:slow=nums[slow]
复杂度分析:
时间复杂度:O(N)
空间复杂度:O(1)