Leetcode287 寻找重复数

这篇博客介绍了一种解决寻找数组中唯一重复数字的方法。通过建立数组与下标的映射关系,利用快慢指针寻找环形链表的入口,从而找到重复的数字。这种方法巧妙地将问题转化为链表问题,解决了空间复杂度限制的问题。

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 [1, n] 范围内(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,返回 这个重复的数 。

你设计的解决方案必须 不修改 数组 nums 且只用常量级 O(1) 的额外空间。

思路:

我们对nums 数组建图,每个位置i连一条i→nums[i] 的边。由于存在的重复的数字target,因此 target 这个位置一定有起码两条指向它的边,因此整张图一定存在环,且我们要找到的target 就是这个环的入口,那么整个问题就等价于 142. 环形链表 II。

如果数组中有重复的数,以数组 [1,3,4,2,2] 为例,我们将数组下标 n 和数 nums[n] 建立一个映射关系 f(n),
其映射关系 n->f(n) 为:
0->1,1->3,2->4,3->2,4->2
同样的,我们从下标为 0 出发,根据 f(n)计算出一个值,以这个值为新的下标,再用这个函数计算,以此类推产生一个类似链表一样的序列。
0->1->3->2->4->2->4->2->……
这里2->4是一个循环,那么这个链表可以抽象为下图:

该链表即为有环链表,使用快慢指针即可找到重复数。
实现代码

class Solution {
    public int findDuplicate(int[] nums) {
        int slow = 0,fast = 0;
        slow = nums[slow];
        fast = nums[nums[fast]];
        while(slow != fast){
            slow = nums[slow];
            fast = nums[nums[fast]];

        }
        fast = 0;
        while(fast != slow){
            slow = nums[slow];
            fast = nums[fast];
        }
        return slow;
        

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值