题目大意:找到数组中唯一的一个重复的数值。时间复杂度要小于O(n^2),不能修改数组了。
发现一个很6的算法,把数组当成一个静态链表,也就是说nums[]数组相当于next[]数组,0为起始节点,节点地址范围就是0-n,一共n+1个节点。
因为数组范围是1-n,所以没有节点next会指向0。
而在有n+1个,next指针的情况下,0为起始节点的链表必然会出现环,也就是两个next指向同一个节点,所以这题其实是相当于寻找链表的环的起始点(方法就是快慢指针,快指针在环里追上慢指针,再让一个指针跑到起始点,然后两个指针同速而行,交点就是答案)。
相关题目:Linked List Cycle II
此方法来源:source
def findArrayDuplicate(array):
assert len(array) > 0
# The "tortoise and hare" step. We start at the end of the array and try
# to find an intersection point in the cycle.
slow = len(array) - 1
fast = len(array) - 1
# Keep advancing 'slow' by one step and 'fast' by two steps until they
# meet inside the loop.
while True:
slow = array[slow]
fast = array[array[fast]]
if slow == fast:
break
# Start up another pointer from the end of the array and march it forward
# until it hits the pointer inside the array.
finder = len(array) - 1
while True:
slow = array[slow]
finder = array[finder]
# If the two hit, the intersection index is the duplicate element.
if slow == finder:
return slow
上面是引用一下,AC代码如下:
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
assert len(nums) > 0
slow = 0
fast = 0
while True:
slow = nums[slow]
fast = nums[nums[fast]]
if slow == fast:
break
slowp = 0
while True:
slow = nums[slow]
slowp = nums[slowp]
if slow == slowp:
return slow