【问题标题】:Time complexity with conditional statements条件语句的时间复杂度
【发布时间】:2016-10-24 06:03:34
【问题描述】:

如何使用可能会或可能不会导致更高阶结果的条件语句计算时间复杂度?

例如:

for(int i = 0; i < n; i++){  
   //an elementary operation   
   for(int j = 0; j < n; j++){
       //another elementary operation  
       if (i == j){  
           for(int k = 0; k < n; k++){
               //yet another elementary operation
           }
       } else {
           //elementary operation
       }
   }
}

如果if-else条件中的内容颠倒了怎么办?

【问题讨论】:

  • 由于 sn-p 是 C、C++ 或 Java 类的,我已将赋值运算符替换为关系相等。如果不是您的意思,请回滚。

标签: code-analysis


【解决方案1】:

您的代码需要 O(n^2)。前两个循环采用 O(n^2) 操作。 “k”循环需要 O(n) 次操作并被调用 n 次。它给出了 O(n^2)。您的代码的总复杂度将是 O(n^2) + O(n^2) = O(n^2)。

再试一次:

 - First 'i' loop runs n times.
 - Second 'j' loop runs n times. For each of is and js (there are n^2 combinations):
     - if i == j make n combinations. There are n possibilities that i==j, 
      so this part of code runs O(n^2).
     - if it's not, it makes elementary operation. There are n^2 - n combinations like that
       so it will take O(n^2) time.
 - The above proves, that this code will take O(n) operations.

【讨论】:

  • 那么条件语句应该用求和规则来处理?
  • 计算复杂性没有一个规则。在您的示例中,“k”循环为每个 i 运行一次。所以它运行了n次。 n*n 是 n^2
【解决方案2】:

这取决于您执行的分析类型。如果您正在分析worst-case complexity,则取两个分支中最复杂的一个。如果您正在分析average-case complexity,则需要计算进入一个或另一个分支的概率,并将每个复杂性乘以选择该路径的概率。

如果你改变分支,只需切换概率系数。

【讨论】:

  • 此算法是确定性的。它将始终运行相同的时间。
  • 你能澄清一下最坏情况的复杂性吗?由于 if 条件,对于给定的示例,采用两个分支的最差复杂性将不起作用
  • 该算法是确定性的,并且不会阻止应用相同的规则,因此您有“n 循环”x“n 循环”x“n 循环每 1/n 次”,其中有“n^ 2" 复杂性。如果切换条件,则有“n 循环”x“n 循环”x“n 循环每 (1 - n/n^2) 次”,其复杂度为“n^3”。注意预期只是某事发生的可能性。事实证明,在谈论确定性算法时,期望就是事实。
猜你喜欢
  • 2020-09-16
  • 2020-06-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
相关资源
最近更新 更多