循环双重不变的时间复杂度

时间:2015-05-01 10:17:05

标签: algorithm time-complexity

我有一个列表数组(即数组中的每个单元格都包含一个列表)。数组的长度为Role Based,所有列表的所有长度之和为n

我想迭代所有列表元素(在整个数组中):

k

注意内循环每次迭代外循环的运行时间少于for(int i = 0; i < n; ++i) { for(int j = 0; j < array[i].list.Length(); ++j) { //do something in O(1) } } 次,但它对所有k的总迭代次数为{{1} }

问题代码的时间复杂度是否为O(n + k)?或者它是O(n * k)?

5 个答案:

答案 0 :(得分:2)

  

问题代码的时间复杂度是否为O(n + k)?或者它是O(n * k)?

都不是。

复杂性为O(n + k)。在n <= k的情况下,这将等于O(k),但情况不一定如此。

n <= k(原始答案)

如果所有长度的总和为k,那么,如果您不在外循环中执行任何其他操作,则运行时间将为O(k)n在这种情况下无关紧要,因为您没有任何有趣的事情n次。您的数据恰好被分成n块。

平均而言,每个列表的大小为k/n。这使得算法O(n * k/n)的时间复杂度导致O(k)

n > k

如果n大于k,则n变得相关,因为每次都必须完成工作,即使它只检查{{1} } Length()。因此,在这种情况下,复杂性为array[i]

更新

正如Jordi Vermeulen在评论中正确指出的那样,我的原始答案只考虑了O(n + k) 不完整的情况。答案已经相应编辑。

答案 1 :(得分:2)

这是O(n + k),当n是O(k)时是O(k)。然而,情况并非如此(如Bart van Nierop的回答所示)。例如,考虑n = k 2 的情况。循环仍然运行k 2 次,所以你不能说复杂度是O(k),即使在很多次迭代中除了增加计数器之外不会做任何工作。

答案 2 :(得分:0)

你应该使用n * k。

  

Foreach cols,处理每一行。

你必须在每一列(n)上做一个循环(for或foreach) 然后在n循环中,你做另一个循环(for或foreach)处理每一行(k)。

for (int i = 0; i < n; i++) {
   for (int j = 0; j < array[i].list.length(); j++) {
     // do something with array[i][j]
   }
}

答案 3 :(得分:0)

对于外部循环的每个i,内部循环运行array[i].list.Length(),您说是k

k times + -+
k times +  |
...        |
...        +--- n times
...        |
k times   -+

因此得到的时间是O(n * k)

答案 4 :(得分:-1)

O(k)。某些部分会发生k次。 在这种情况下,n无关紧要。