【问题标题】:Calculating running time of a while loop [duplicate]计算while循环的运行时间[重复]
【发布时间】:2018-10-17 19:03:16
【问题描述】:

我只是从算法开始,我试图找出下面 while 循环的运行时间,以 'n' 表示。

int k=1;
while(k<n-k){
k+=k;
}

这里 n>2。我知道 k 的值每次都会翻倍,并且循环只运行一次,一旦 k 值大于 n/2。但是我很难用“n”来表达。

【问题讨论】:

    标签: c++ algorithm time-complexity


    【解决方案1】:

    值得列出重点:

    • k 在每次循环迭代中翻倍

    • 您的循环条件可以重写为:while(2*k &lt; n)*

    基本问题是:我必须 加倍k 多少次,直到 k 加倍 等于或大于 @987654325 @?

    这很容易。这正是对数的工作原理。以号码2 为例。我必须翻倍多少次才能达到,比如说,1000?答案是 log21000 向上取整。

    本质上,您的算法是log_2(n) - 1,这意味着您的算法以对数时间复杂度运行。


    *正如 François Andrieux 在他的评论中正确陈述的那样,虽然这个陈述在数学上是正确的,但由于数据类型的表示限制,编程中并非总是如此。对于较大的ks,表达式2*k 可能会导致溢出并使整个表达式无效,而对于相同的输入,表达式k &lt; n-k 将正常运行。

    【讨论】:

    • 虽然它不会改变答案的正确性,但我想指出,由于ksigned int2*k &lt; n 并不完全等同于k &lt; n-k,因为如果n 足够大,第一个表单可能会溢出。
    • 这是一个非常有效的观点,应该得到解决。我将很快将此评论添加到我的答案中。谢谢
    【解决方案2】:

    替换

      while(k<n-k)
         k+=k;
    

    等价

      while(2*k<n)
        k*=2
    

    最后一个肯定是O(log(n)) - 它使log2(n)-1 步骤

    【讨论】:

      【解决方案3】:

      表达式k &lt; n-k 简化为k &lt; n/2

      时间复杂度应为O(log(n)),基数为 2

      K = 1 -> 2 -> 4 -> 8 -> ... -> m iterations
      
      2^(m-1) < n/2
      
      m-1 < log2(n/2)
      
      m ~ log2(n)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-09-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-23
        • 1970-01-01
        • 1970-01-01
        • 2022-01-22
        相关资源
        最近更新 更多