O(2m + n)和O(kn)的时间复杂度

时间:2018-03-25 15:55:15

标签: c++ performance time-complexity

例如,假设有一个函数迭代大小为m两次的数组和一次大小为n的数组

func(){
   for(i = 0; i < m; i++){//do something}
   for(i = 0; i < n; i++){//do something}
   for(i = 0; i < m; i++){//do something}
}

将时间复杂度写为O(2m + n)= O(m + n)是否正确,因为O(2m)= O(m)?

另一个问题是,如果我有一个迭代大小为n的数组的函数,k次,其中k是在调用函数之前从输入计算的。

func(int k){
    for(int i = 0; i < k; i++){
        for(int j = 0; j < n; j++){}
    }
}

可以说它的时间复杂度是O(k * n)= O(n),原因与第一个问题相同吗?

4 个答案:

答案 0 :(得分:4)

第一个是正确的,因为数字2是常数,因此它对时间干涉没有区别。

然而,第二个可能既错又正确。如果将k视为永不改变的常量,则时间复杂度为O(n)。但是,如果k是可变的,则时间复杂度严格为O(kn),因为k可以增加或减少,因此它会使渐近时间复杂度产生差异。

因此,在您的情况下,复杂性严格为O(kn)

答案 1 :(得分:4)

  

将时间复杂度写为O(2m + n)= O(m + n)是否正确,因为O(2m)= O(m)?

是。大表达式的术语可以分成单独的大表达式,因此O(2m+n) = O(2m) + O(n) = O(m) + O(n) = O(m+n)

  

可以说它的时间复杂度是O(k * n)= O(n),原因与第一个问题相同吗?

不,因为k不是常数。

答案 2 :(得分:3)

在第一个有3个循环的函数中,其中两个从(零)到(m)开始,第三个函数从(零)到(n)开始,所以这个函数的时间复杂度 o( 2m + n) = o(m + n) = o(n),这种情况称为“线性时间复杂度” 这意味着当(m)或(n)的值增加时,时间复杂度线性增加,因此第一个函数的时间复杂度为真

在第二个函数中有两个嵌套循环,内部循环从(零)开始到(n)和重复(k)次,例如if(k = 3)和(n = 2),这意味着内部循环从(零)到(2)开始并重复3次,因此时间复杂度为o(2 + 2 + 2)= o(2 * 3)= o(n k), 所以第二个函数的时间复杂度是 o(n k)

答案 3 :(得分:2)

让我们从大O的定义中谈谈这个:

  

我们说f(n)= O(g(n)),如果对于任何正n 0,存在常数C = C(n 0),使得对于任何n> 0。 n 0,f(n)≤Cg(n)是真的。

所以,在你的第一种情况下,如果我们选择一个常数C,如2,我们有O(2m + n)≤O(2m + 2n)= O(m + n)。

但对于第二种情况,对于您选择的任何C,存在这样的k以使要求失败,因此第二种情况不能是O(n)。事实上它是O(kn)。 (如果变量k被调节,你可以说它是O(n),在这种情况下你可以选择一个大于k的上限的C)