leetcode(287). Find the Duplicate Number

来源:互联网 发布:macbook免费清理软件 编辑:程序博客网 时间:2024/05/14 13:34

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]整数的题时可以用这样的方式写出来,寻找规律。