【问题标题】:Time complexity for a nested for loop嵌套 for 循环的时间复杂度
【发布时间】:2020-09-22 23:04:32
【问题描述】:

给定以下嵌套的 for 循环:

for (int i=n; i>1; i=i/2):
    for (int j=i; j<n; j=j*2)
        # O(1) expression

整个循环的时间复杂度是多少?我的答案是 O(log(n)*log(n)) 但我不确定它是否正确。

【问题讨论】:

  • 是的,答案是 O(log(n) * log(n)),但可能不是你想的那样。你是怎么得出这个答案的?

标签: algorithm time-complexity big-o


【解决方案1】:

这是使用格言的好地方

如有疑问,请由内而外!

也就是说,从最里面的循环开始,并用一个表示它正在做多少工作的表达式替换它,然后重复这个直到你完成。

在你的情况下,最里面的循环是

for (int j=i; j<n; j=j*2)
    # O(1) expression

现在,这做了多少工作?为了回答这个问题,让我们考虑一下循环是如何工作的。在每次迭代中,j 的值都是之前的两倍。由于 j 从 i 开始,j 取的值将是 i、2i、4i、8i 等,更一般地,在循环的第 k 次迭代中,j 的值将是 2k ·一世。一旦这个值等于或超过 n,循环就会终止,这发生在

2k · i = n

2k = n / i

k = lg(n / i)

所以这意味着我们将运行循环进行 Θ(log (n / i)) 次迭代。如果我们将其替换为原始循环,我们将得到以下代码:

for (int i=n; i>1; i=i/2):
    Do Θ(log (n / i)) work;

那么最终总共需要多少工作量?好吧,外部循环将运行一次 i = n,然后运行一次 i = n/2,然后运行一次 i = n/4,等等,所以完成的总工作是

Θ(log (n/n) + log(n/(n/2)) + log(n/(n/4)) + ... + log(n / 1))

= Θ(log 1 + log 2 + log 4 + log 8 + ... + log n)

= Θ(log 20 + log 21 + log 22 + log 23 + ... + log 2log n)

Θ(0 + 1 + 2 + ... + log n)

记住 0 + 1 + 2 + ... + k = k(k + 1) / 2 = Θ(k2),所以这里做的总功是

Θ(0 + 1 + 2 + ... + log n)

= Θ(log2 n).

得出这个答案的关键技术是从内部开始,将对数与重复将大小翻倍时执行的循环迭代次数联系起来,以及 1 + 2 + ... + k 的公式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-05-18
    • 2021-02-15
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多