Leetcode287. Find the Duplicate Number(寻找重复数)创新解法

最近刷到一道medium难度但方法很创新的题。题目简要叙述如下:
数组nums长度为n+1,1<=nums[i]<=n,且满足恰好有一个重复数字。要求不能修改原数组nums、时间复杂度小于O(n^2)、空间复杂度O(1)找出这个重复数字。

乍一看题目要求很高,实际上凭空想根本就想不出来。看了Leetcode给的答案才发现题目要求是为答案量身定制的。思路如下:

由于nums.length == n + 1, 1 <= nums[i] <= n,故nums[nums[i]]有定义。
若令i := 0
重复:生成节点node[i],节点的值为nums[i],节点的next值为nums[nums[i]],
i := nums[i]
结束
则可生成有循环的链表如下图。必有2个节点的next值指向同一个节点,这个节点的值即为重复的数字。
在这里插入图片描述
运行Floyd的龟兔赛跑算法:指针hare和tortoise初始指向链表头节点,hare每次前进两步,tortoise每次前进一步,则兔子必在环内追上乌龟。追上时兔子走的距离是乌龟的2倍,即
(F + a) * 2 = F + a + n * C
其中F是入环之前的距离,a是环内走的距离,C是环的步数,n是环数。

F + a = n * C
兔子追上乌龟后,兔子再从链表头出发,乌龟从追上的位置原地出发,每次均向前移动一步,则经过F步后,兔子走了F步到了入环节点,乌龟在环内共走a + F = n * C步,也是入环节点,此时他们相遇作为判断条件。入环节点的值就是重复数字。

public int findDuplicate(int[] nums) {
        int tortoise = nums[0], hare = nums[nums[0]];
        while (tortoise != hare) {
            tortoise = nums[tortoise];
            hare = nums[nums[hare]];
        }
        tortoise = 0;
        while (tortoise != hare) {
            tortoise = nums[tortoise];
            hare = nums[hare];
        }
        return hare;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值