如何从Leetcode理解快乐数问题解决方案的时间复杂性

时间:2019-11-21 14:49:20

标签: time-complexity

我在理解Leet代码中的“快乐数字”问题的一种解决方案的时间复杂度分析时遇到一些困难,由于对复杂度分析的怀疑,我将其粗体显示,并非常感谢您的建议

这是问题:

链接:https://leetcode.com/problems/happy-number/

问题:

编写一种算法来确定数字是否“幸福”。 一个快乐的数字是由以下过程定义的数字:从任何正整数开始,用该数字的平方和代替该数字,然后重复该过程,直到该数字等于1(它将停留在该位置),否则它就会循环在不包含1的循环中无休止地进行下去。此过程以1结尾的数字是快乐数字。

示例:

输入:19

输出:true

说明:

1 ^ 2(1的平方)+ 9 ^ 2 = 82

8 ^ 2 + 2 ^ 2 = 68

6 ^ 2 + 8 ^ 2 = 100

1 ^ 2 + 0 ^ 2 + 0 ^ 2 = 1

代码如下:

class Solution(object):
    def isHappy(self, n):
        #getnext function will compute the sum of square of each digit of n
        def getnext(n):
            totalsum = 0
            while n>0:
                n,v = divmod(n,10)
                totalsum+=v**2
            return totalsum
        #we declare seen as a set to track the number we already visited
        seen = set()
        #we stop checking if: either the number reaches one or the number was visited #already(ex.a cycle)
        while n!=1 and (n not in seen):
            seen.add(n)
            n = getnext(n)
        return n==1

注意:如果需要解释代码的工作原理,请随时告诉我

时间复杂度分析:

时间复杂度:O(243 * 3 + logN + loglogN + log loglog N)... = O(logN)。

查找给定数字的下一个值的成本为O(log n),因为我们正在处理数字中的每个数字,并且数字中的数字位数由logN给出。 我的疑问:为什么数字中的位数由logN给出?这里的N是什么?特定数字或其他值的值?

要计算总时间复杂度,我们需要仔细考虑链中有多少个数字,以及它们有多大。

我们在上面确定,一旦数字低于243,就不可能再回到243以上。因此,基于我们的浅层分析,我们可以确定一旦数字低于243,就不可能终止操作还需要243多个步骤。

每个数字最多包含3位数字。经过更多的分析,我们可以将最长的数字链的长度替换为243,并将其替换为243以下的最长数字链的长度,但是由于常量无论如何都不重要,因此我们无需担心。 我的疑问:我认为上一段与243 * 3的时间复杂度成分有关,但我不明白为什么我们将243乘以3

对于大于243的n,我们需要考虑链中大于243的每个数字的成本。通过一点数学运算,我们可以证明在最坏的情况下,这些成本为O(log n)+ O(log log n)+ O(log log log N)...对我们来说幸运的是,O(logN)是主要部分,而其他所有参数相比而言都是很小的(总的来说,它们的总和小于logN) ,因此我们可以忽略它们。 我的疑问:对于大于243的n,O(log log n)O(log log log N)背后的原因是什么?

2 个答案:

答案 0 :(得分:1)

好吧,我对第一个疑问的猜测是,以10为底的数字的位数是由它的值(N)取为以10为底的对数的整数。因此,例如1023将有floor(log10(1023))位数字,即3。所以,是的,N是数字的值。时间复杂度上的log表示对数,而不是对数2或e的对数。

关于第二个疑问,这可能与将数字减少到243以下所需的工作有关,但是我不确定。一旦完成工作,我将编辑此答案。

答案 1 :(得分:0)

假设NM位数字。比getnext(N) <= 81*M。当N仅具有9时,将发生平等。

  • N < 1000时,即最多3位,getnext(N) <= 3*81 = 243。现在,您最多只能拨打getnext(.)O(243)来确定N是否确实很开心。

  • 如果为M > 3,则getnext(N)的位数必须小于M。尝试使用getnext(9999)getnext(99999)等[1]。

注释:

[1]在N上添加一个数字最多可以使其10*N + 9,即在末尾添加9。但是位数只会增加到M+1。这是NM之间的对数关系。因此,N81*M之间保持着相同的关系。