给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
PS:
不能更改原数组(假设数组是只读的)。
只能使用额外的 O(1) 的空间。
时间复杂度小于 O() 。
数组中只有一个重复的数字,但它可能不止重复出现一次。
二分法(统计小于二分查找字符的次数):
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
n = len(nums)
left, right = 0, n - 1
while(left <= right):
mid = left + right >> 1
count = 0
for i in range(n):
count += nums[i] <= mid
if count <= mid:
left = mid + 1
else:
right = mid - 1
ans = mid
return ans
时间复杂度O(nlogn), 空间复杂度O(1)
快慢指针(Floyd 判圈算法,快指针走两步,慢指针走一步,如果有环他们总会相遇, 相遇后再将slow置零,两个指针都变为一步,再次相遇的点就是答案):
class Solution:
def findDuplicate(self, nums: List[int]) -> int:
fast, slow = 0, 0
# 初始状态
slow = nums[slow]
fast = nums[nums[fast]]
while(slow != fast):
slow = nums[slow]
fast = nums[nums[fast]]
slow = 0
while(slow != fast):
slow = nums[slow]
fast = nums[fast]
return slow
时间复杂度O(n), 空间复杂度O(1)
二进制:类似于二分法的计数,这里用来确定二分位上每一位重复是1还是0。
时间复杂度O(nlogn), 空间复杂度O(1)