繁体   English   中英

就 Big O 而言,该解决方案的运行时间复杂度和空间复杂度是多少?

[英]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 - 1f(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) + 1001O(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM