[英]What is the Run Time Complexity and Space Complexity of this solution in terms of Big O?
我相信空间复杂度只是 O(n),因为该集合是整个程序中唯一存储的集合,并且每次都会重新计算列表。 我不确定时间复杂度是否为 O(n^2),因为有一个 while 循环并且内部有一个 for 循环,或者它是否有所不同,因为如果 n 永远不会是 1 或在集合中。
def isHappy(self,n):
seen = set()
while True:
if n not in seen:
seen.add(n)
n = sum([int(x) * int(x) for x in str(n)])
if n == 1:
return True
else:
return False
先前关于平均时间复杂度的陈述是不正确的,因为它没有考虑n
十进制数字平方和的复杂性。
由于缺乏数学格式,请提前原谅我。 在 StackOverflow 帖子中没有简单的方法可以做到这一点。
简短的回答是您的解决方案不会进入无限循环,它确实具有O(n)
空间复杂度和O(n**2)
时间复杂度。
这是长答案:
让f(n)
表示对n
的十进制数字的平方求和的结果,就像在while
循环中所做的那样。 如果n
有四位或更多位,则保证f(n)
的位数少于n
,如
f(9999) == 4 * 9**2 == 324
,并且10**k - 1
和f(10**k - 1)
之间的差异随着k
的增加而增加。 因此,对于具有四位或更多位的n
,最多需要log10(n)
次循环迭代才能得到一个三位数的数字。 并作为
f(999) == 3 * 9**2 == 243
,无论您将n = f(n)
应用于三位或更少位数的n
多少次,结果也将包含三位或更少位数。 只有 1000 个非负整数具有三个或更少的数字,因此根据鸽洞原理,在最多 1001 次迭代后, f(n)
要么等于 1,要么已经包含在集合中。 总的来说,这不大于循环的log10(n) + 1001
次迭代,在这种情况下, n
指的是 function 参数的原始值。
对于set
s
,在最坏的情况下,插入和成员资格测试都是O(len(s))
。 由于集合只能包含与过去迭代一样多的元素,
len(s) <= log10(n) + 1001.
并且log10(n) + 1001
是O(n)
(但不是O(log(n))
,因为复杂性是根据输入的大小(位数),而不是输入本身)。 并且由于在给定的迭代过程中, n
的位数要么少于其原始位数,要么少于四位数,因此位数的平方和也是O(n)
。 总的来说,这是O(n)
次迭代,每次O(n)
,最坏情况的总时间复杂度为O(n**2)
。
如上所述,无论n
有多大,都可以保证最终达到三位数,因此您实际上可以将集合替换为 1000 个布尔值的列表。 然后解决方案将具有O(1)
空间复杂度。
最好的情况是O(1)
假设如果程序在第一次尝试中得到答案,最坏的情况可能是O(n^2)
,因为循环一次又一次地迭代自己,但是如果你想要一个比您可以考虑添加一个新常量,它将代表以下循环
sum([int(x) * int(x) for x in str(n)])
让我们用常数r
表示这个循环,那么最坏情况的复杂度将变为O(n^2 + r)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.