这个问题(解决leetcode问题650)的时间复杂度是多少?

时间:2019-06-26 22:01:09

标签: python-3.x algorithm data-structures dynamic-programming bottom-up

您好,我一直在研究https://leetcode.com/problems/2-keys-keyboard/submissions/,并遇到了这个动态编程问题。

您在空白页上以'A'开头,完成后会得到数字n,在页面上应该用n乘以'A'。要注意的是,您只能进行2次操作复制(并且您只能复制页面上当前的A总数)并粘贴->找到在页面上获得n'A'的最小操作数

我写了下面的算法来解决这个问题,但是我在分析它的时间复杂度上却很费力。

代码如下:

    def minSteps(self, n: int) -> int:
        DP = [0] + [0] + [i for i in range(2, n+1)]

        for d in range(2, n+1):
            for i in range(d*2, n+1, d):
                DP[i] = min(DP[i], DP[d] + i//d )
        return DP[n]

所以我的直觉说,此算法在O(n^2)O(nlogn)之间,因为在第二个循环中我们比O(n)更快,但是由于步长{{1} }不会在每次迭代之间加倍,但在第二个循环中仍然是d ...

我不确定该如何分析,欢迎任何帮助。

2 个答案:

答案 0 :(得分:2)

让我们看一下外部循环-它执行了O(N)次。
每个内部循环都在执行O(N / d)操作,因为索引的跳转位于d中。
因此计算为:

N / 1 + N / 2 + N / 3 + ... + 1

请注意,这笔款项中有N个项目。

我们可以取出N

N * (1 / 1 + 1 / 2 + 1 / 3 + ... + 1 / N)

大约是:

N * ln N

(直觉是,通过集成函数1 / N,您会得到ln

因此,总体复杂度为O(N log N)

答案 1 :(得分:0)

您的解决方案是O(nlogn)。这是一个更有效的解决方案:

 def minSteps(self, n: int) -> int:
        ans = 0
        d = 2
        while n >= d * d:
            while n % d == 0:
                ans += d
                n //= d
            d += 1
        if n != 1:
            ans += n
        return ans 

此解决方案基于LeetCode上发布的解决方案,但速度更快。时间复杂度为O(sqrt(p)),其中pn的最大素数。