例如,假设有一个函数迭代大小为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),原因与第一个问题相同吗?
答案 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)