https://leetcode.com/problems/find-the-duplicate-number/description/
题目大意:n+1个数,有1个数字重复了多次,找出来。要求不能用额外的空间,不能改变数组内容。
解题思路:第一想法是排序,但是这要么要改变数组内容,要么需要额外的空间。
考虑如下的一个序列:
idx | 0 | 1 | 2 | 3 | 4 |
val | 1 | 3 | 4 | 2 | 2 |
从idx=0开始,对应的val是下一个idx,建立一个类似链表的结构, 1->3->2->4->2 将会出现一个环,之后就是链表判环的解法,可以用快慢指针来做。环的入口就是重复的数字。
下面简单分析一下,因为现在肯定存在重复的数字,假设重复的数字的个数有两个,分别对应的idx为x,y ,那么肯定存在一个值为x的 和 nusm[x] 相连,也肯定存在一个值为y的 和 nums[y]相连, 这个nums[x]==nums[y]就是重复数字,也是环的入口。
class Solution {
public int findDuplicate(int[] nums) {
int slow=nums[0],fast=nums[0];
do
{
slow = nums[slow];
fast = nums[fast];
fast = nums[fast];
// System.out.println(slow+" "+fast);
}while(fast!=slow);
fast =nums[0];
while(fast!=slow)
{
fast = nums[fast];
slow = nums[slow];
// System.out.println(slow+" "+fast);
}
return fast;
}
}