leetcode(287). Find the Duplicate Number

本文介绍了一种利用链表环原理在不修改原始数组且使用常数级额外空间的情况下,寻找长度为n+1的数组中重复数字的方法。该方法通过将数组转化为链表,并利用快慢指针找到环的入口来确定重复的数字。

problem

Given an array nums containing n + 1 integers where each integer is
between 1 and n (inclusive), prove that at least one duplicate number
must exist. Assume that there is only one duplicate number, find the
duplicate one.

Note:
You must not modify the array (assume the array is read only).
You must use only constant, O(1) extra space.
Your runtime complexity should be less than O(n2).
There is only one duplicate number in the array, but it could be repeated more than once.

分析

看到题目中的描述长度为n+1的数组中的数字属于[1, n],就可以想到把数组改造成一个链表,即array[i].next = array[array[i]],对于这样的链表如果有环的话,那么就意味着有多个数指向一个位置,那么这个指向的数就是我们要找的重复的数字。

例如数组[5, 4, 3, 1, 2, 1],[0, 5]→[5, 1]→[1, 4]→[4, 2]→[2, 3]→[3, 1]→[1, 4]……(前面的数字表示index,再做这种类型内容为[1, n]整数的题时可以用这样的方式写出来),从这个例子中可以看出[3, 1]和[5, 1]都指向了[1, 4],所以1就是重复的数字。而一定存在重复的数字就表明一定有这样的环,因为有n+1个数字,只有n个位置,所以一定有指向同一个位置的两个元素。

通过以上分析可以知道,我们只需要找到环的入口的数字即可,只需对leetcode(142). Linked List Cycle II稍作修改即可。

class Solution(object):
    def findDuplicate(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        # 超过了90%的提交
        slow = nums[0]
        fast = nums[nums[0]]

        while slow != fast:
            slow = nums[slow]
            fast = nums[nums[fast]]

        fast = 0
        while fast != slow:
            fast = nums[fast]
            slow = nums[slow]

        return slow

总结

[5, 4, 3, 1, 2, 1],[0, 5]→[5, 1]→[1, 4]→[4, 2]→[2, 3]→[3, 1]→[1, 4]……(前面的数字表示index),再做这种类型内容为[1, n]整数的题时可以用这样的方式写出来,寻找规律。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值