287. 寻找重复数 - 力扣(LeetCode) (leetcode-cn.com)
思路:
见代码,index->num视为有向图,然后借助必定有环的性质,采取 这道题的做法
,找到环的入口,这个入口的idex就是重复的值了。
代码:
public int findDuplicate(int[] nums) {
//方法1暴力寻找,O(n²)
//方法2,排序,然后遍历一次O(logn)+O(n)
//方法,通过下标->元素值的映射,抽象成链表,
//由于元素范围在[1,n],且下标在[0,n]所以,下标->元素的 n->f(n)不能完全一一对应,
//会多出一个下标对应任意一个元素,让本来一一对应的所有关系形成的一条链路,某处一定会成一个环
//因此,基于此,从下标0开始,分把设置快慢指针即可,快指针比慢指针每步多走一次,
//把这些index -> num视为一个有向图,故图一定有环,
int fast=0;
int slow=0;
//同一出发点出发,直到相遇为止(),然后套用公式算出出发点到环入口的距离,即答案
do{
fast = nums[nums[fast]];
slow = nums[slow];
} while(nums[fast]!=nums[slow]);
//相遇之后,设置一个指针从0开始走,慢指针继续走,他们相遇的时候就是环入口,即该index就是重复值
int ans = 0;
while(ans != slow){
ans = nums[ans];
slow = nums[slow];
}
return ans;
}