我在leetcode中解决了一个问题
给定包含n + 1个整数的数组nums,其中每个整数在1和n之间(包括1和n),证明必须存在至少一个重复的数字。假设只有一个重复的数字,在O(n)时间和O(1)空间复杂度中找到重复的数字
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
xor=0
for num in nums:
newx=xor^(2**num)
if newx<xor:
return num
else:
xor=newx
我接受了解决方案,但我被告知它既不是O(1)空间也不是O(n)时间。
任何人都可以帮我理解为什么吗?
答案 0 :(得分:6)
你的问题实际上很难回答。通常在处理复杂性时,会假设机器模型。 A standard model假设当输入大小为n时,内存位置的大小为log(n)位,而对log(n)位大小的数字的算术运算为O(1)。
在此模型中,您的代码在空间中不是O(1),在时间上不是O(n)。你的xor
值有n位,这不适合常量内存位置(它实际上需要n / log(n)内存位置。同样,它不是O(n)及时,因为算术运算是在大于log(n)位的数字上。
要在O(1)空间和O(n)时间内解决您的问题,您必须确保您的值不会太大。一种方法是xor数组中的所有数字,然后你会得到1^2^3...^n ^ d
,其中d
是重复的。因此,您可以从数组的总xor中xor 1^2^3^..^n
,并找到重复的值。
def find_duplicate(ns):
r = 0
for i, n in enumerate(ns):
r ^= i ^ n
return r
print find_duplicate([1, 3, 2, 4, 5, 4, 6])
这是O(1)空间,而r
以来的O(n)时间从不使用比n
更多的位(即大约ln(n)位)。
答案 1 :(得分:0)
您的解决方案不是O(1)空格,意思是:您的空间/内存不是常量,但取决于输入!
newx=xor^(2**num)
这是log_2(2**num) = num
位的逐位XOR,其中num
是您的输入数字之一,导致log_2(2**num) = num
位结果。
所以n=10 = log_2(2^10) = 10 bits
,n=100 = log_2(2^100) = 100 bits
。它呈线性增长(不恒定)。
你得到的时间复杂度也不在O(n)之内: