下面给出的是问题陈述和解决方案。我无法理解解决方案背后的逻辑。查找数组中的重复 - 时间复杂度<O(n^2)和常量额外空间O(1)。 (亚马逊访谈)
问题陈述:
鉴于包含n + 1点的整数,其中每个整数是1和n(含)之间的阵列NUMS,证明至少有一个重复的数目必须存在。假设只有一个重复号码,找到重复号码。
注意: 您不得修改数组(假定数组是只读的)。 您只能使用恒定的O(1)额外空间。 您的运行时复杂度应该小于O(n2)。 数组中只有一个重复数字,但可以重复多次。
采样输入:[3 4 1 4 1] 输出:用于贴在本文给出了问题1个
的解是:
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
low = 1
high = len(nums)-1
while low < high:
mid = low+(high-low)/2
count = 0
for i in nums:
if i <= mid:
count+=1
if count <= mid:
low = mid+1
else:
high = mid
return low
说明用于上述代码(按作者): 该解决方案基于二分查找。
首先搜索空间是1到n之间的数字。每次我选择一个数字(这是中间的数字),并计算所有等于或小于中等数字的数字。然后,如果计数超过中间值,搜索空间将为[1 mid],否则为[mid + 1 n]。我这样做直到搜索空间只有一个数字。
假设n = 10,我选择mid = 5。然后我计算数组中所有小于等于中间的数字。如果5个以上的数字小于5,那么按照鸽王原理(https://en.wikipedia.org/wiki/Pigeonhole_principle),其中一个已经出现过一次以上。所以我缩小了从[110]到[1 5]的搜索空间。否则重复号码在下半部分,因此下一步搜索空间将会是[6 10]。
的疑问:在上述方案中,当count <= mid
,我们为什么要改变low
到low = mid + 1
或以其他方式改变high = mid
? 它背后的逻辑是什么?
我无法理解这种算法
'[3 4 1 4 1]'有两个副本,1 4. –
实际上这个代码容忍多个副本,并输出最小的一个。 –
是的,如果有多个重复项,它会输出其中的任何一个。 – kshikhar