【问题标题】:Time complexity when halving loop counter twice将循环计数器减半时的时间复杂度
【发布时间】:2020-01-04 15:20:25
【问题描述】:

我知道我们将循环计数器减半时的时间复杂度是log n。也就是说,如果我们有以下循环:

for(i=1 ; i<n ; i*=2) { ... }

那么时间复杂度是log n

不应该将循环计数器i 再次减半给log log n 时间复杂度吗?那就是下面的循环

for(i=1 ; i<n ; i*=4) { ... }

时间复杂度是log log n

我尝试了n 的一些值:

n = 2^8 = 256
i = 1,4,16,64,256 (5 times)

n = 2^10 = 1024
i = 1,4,16,64,256,1024 (6 times)

n = 2^16 = 65536
i = 1,4,16,64,256,1024,4096,16384,65536 (9 times)

似乎循环体被执行了(log n)/2-1 次。 我对这个分析是否正确并且将循环计数器减半确实仍然给出O(log n) 时间复杂度而不是O(log log n) 时间复杂度?

【问题讨论】:

    标签: algorithm time-complexity


    【解决方案1】:

    你忘记了基地。在第一种情况下,我们假设基数为 2,因此我们只需将复杂度写为 O(logn)

    在第二种情况下,基数应该是 4,因为我们要乘以 4,所以它应该是 O(log4n)

    【讨论】:

    • 我知道如果我这样做i=i^2,我会得到O(log log n) 的时间复杂度。做i*=k,得到O(log_k(n))。做i=i^k 有什么相似之处吗?比如i=i^4就是O(log log log log n)
    • @anir,您不应该在 cmets 中扩展您的原始问题。如果您有新问题,请以适当的方式提出新问题。同时决定在此处将哪个答案标记为已接受。
    • 请注意O(log_4(n)) = O(0.5 * log_2(n)) = O(log_2(n))。基地无所谓
    【解决方案2】:

    对,这就是为什么我们说O(log n),而不仅仅是log n。顺便说一句,对于实际日志 n,您必须循环使用 *e 或类似的东西

    如果您使用*4 循环,它只会快两倍,并且仍然是O(log n)

    为了得到 O(log log n) 你必须每次改变你的增加:

    i*=2
    i*=4 (= 2*2)
    i*=16 (= 4*4)
    i*=256 (= 16*16)
    etc
    

    【讨论】:

    • Q1.改变增长背后的直觉是什么?
    • Q2. 我开始知道如果我这样做 i=i^2 我会得到 O(log log n) 时间复杂度。与此相比,变化增加如何?
    • 对于 Q1 - 在每一步 m 的功率将是 a^(a^m)(在我的情况下是 2^(2^m))所以 m 将是 O(log log i)。对于 Q2 - 你是对的,这非常相似,功率将为 1、2、4、16、256 等,因此日志将为 0、1、2、4、8 等,因此 log log 将为 1,2,3,4,... 即迭代次数。
    • @anir,您不应该在 cmets 中扩展您的原始问题。如果您有新问题,请以适当的方式提出新问题。同时决定在此处将哪个答案标记为已接受。
    • @trincot 我知道扩展问题可能不是很好。但这些都是相关的问题。如果我必须提出新问题,我必须重新建立这个问题的上下文,因为我在问其他形式的迭代与此相比如何。通过提出多个相关问题从不同方向攻击同一概念也有助于清楚地掌握概念。
    猜你喜欢
    • 1970-01-01
    • 2021-02-18
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 2022-09-22
    • 2020-08-13
    • 1970-01-01
    相关资源
    最近更新 更多