while 循环的时间复杂度

Posted

技术标签:

【中文标题】while 循环的时间复杂度【英文标题】:Time complexity with while loops 【发布时间】:2013-12-08 14:05:54 【问题描述】:

我完全不确定我是否了解时间复杂度的计算。我得到了这些循环,这些是我的计算。但是,对于这里的大 O,我完全不知道该说什么。

循环 1:

lst = []                   
i=1                        
while i<n:
  lst = list(range(i))       
  i *= 2 

我假设每个操作都需要 O(1) 时间。在这个循环中,第一行和第二行各执行 1 次。 while 循环的第一行有 3 个操作 - 范围、列表和将该值分配给 lst。由于我们正在处理范围,我假设它运行 n+1 次。

循环的最后一行有 2 个操作:乘以 2 并将该值分配给 i,它运行 n 次。

据此,我认为总数为: 1+1+3(n+1)+2n = 5n+5。

既然这是一个线性函数,那么大O就是O(n)?

================

循环 2:

lst = []            
i=1                 
while i<n:
  lst = lst + [i]      
  i *= 2    

这里我们有一个类似的情况,但是 while 循环的第一行有 2 个操作。 那么, 1+1+2n+2n = 4n+2。

既然是线性函数,那也是O(n)?

=========================== 循环 3:

lst = []          
i=1                
while i<n:
  lst += [i]         
  i *= 2  

我认为 lst +=[i] 会有 2 个操作执行 2n 次,因为这是就地计算?我不确定这一点。如果这是正确的,那么总数将是 6n+2

问题是:我计算这些是正确的还是完全错误的?如何为每个循环写大 O?

【问题讨论】:

今天早些时候发布了第二个 here。它可能会帮助你理解所有这些。 也许这在Computer Science Stack Exchange 上更合适。 你需要考虑while循环执行了多少次。 首先想想它像sweeneyrod所说的那样循环了多少次,然后想想每次迭代都做了什么。在考虑迭代次数时,不要使用实际数字,只需考虑它与n 的关系。 i 每次翻倍吗?然后它将以log2(n) 为增量达到n @KEYSER 我知道每个循环将迭代 log2n 次,因为在每种情况下 i 都加倍。让我感到困惑的是除了 i 的加倍之外的其他操作,尤其是 += 和常规加法之间的区别。 【参考方案1】:

循环 1:O(n log n)

循环运行 log2(n) 次,平均为 O(log n)。每次迭代(在最坏的情况下)执行 n 个动作。所以复杂度是 O(n log n)。

循环 2:O(log n)

循环运行 log2(n) 次,平均为 O(log n)。 我想分配lst = lst + [i] 只是添加节点(而不是创建新列表)。它的平均值为 O(1),因此复杂度为 O(log n)。 如果我错了,分配会创建新列表,因此每次迭代都会(在最坏的情况下)执行 n 个操作。所以复杂度是 O(n log n)

循环 3:O(log n)

与循环 2 一样。这里的赋值肯定是 O(1),而不是假设...

【讨论】:

以上是关于while 循环的时间复杂度的主要内容,如果未能解决你的问题,请参考以下文章

包含while循环的算法的时间复杂度

汽车加油问题(贪心算法),O(n) 复杂度的嵌套 while 循环

以下代码的时间复杂度是多少?

算法优化分析---打印素数

有循环就是O(n)时间复杂度吗?

JavaScript day03 循环