【问题标题】:Time complexity of filter with a nested loop具有嵌套循环的过滤器的时间复杂度
【发布时间】:2021-12-30 11:53:54
【问题描述】:

我对 Big O 很陌生,我不确定以下代码的时间复杂度是多少:

const items = [
  {type: 'phone', name: 'iPhone', color: 'gold'},
  {type: 'phone', name: 'Samsung', color: 'gold'},
  {type: 'laptop', name: 'Chromebook', color: 'gray'},
  {type: 'tv', name: 'LG', color: 'gray'},
  {type: 'gooo', name: 'LG', color: 'silver'},
  {type: 'phone', name: 'Nokia', color: 'gold'}
];

items.filter(item => {
    for(let i=0; i < Object.keys(item).length; i++) {
        console.log('item is', Object.keys(item)[i])
    }
})

我们可以说这是O(i + c),其中iitemsc 是常量console.log?或者我们需要说O(i * j + c) 之类的话,其中j 是个人item,即{type: 'phone', name: 'iPhone', color: 'gold'}

谁能帮帮我...提前谢谢你!

【问题讨论】:

  • 您要归档什么?因为你的过滤方法并没有真正过滤任何东西
  • 它实际上有点复杂,因为您调用 Object.keys() 的方式本身具有 O(n) 的复杂性(您在 for 条件下每次迭代调用一次并再次调用它在 console.log 中)请参阅:Object.keys() complexity?

标签: javascript filter time-complexity big-o


【解决方案1】:

items.filter(() =&gt; { ... }) 是一个循环 => O(n)

您在其中有一个 for 循环遍历对象键 => O(m * n)

Object.keys() 在 V8 中是 O(m),你在 for 循环中有两次(在条件下,所以它在每次迭代和循环体中都被调用)所以它是 => O(m ^ 2 * n)(其中 @ 987654329@ 是键的数量)。

你也可以使用

for (let key in item) {
  // and do whatever you want with the key
}

而不是使用Object.keys

【讨论】:

  • 内循环不是n,而是m,因为它是item.keys的长度
  • 哦!对不起,我错过了。谢谢,@pilchard
  • 为什么是O(n^2)?内部循环不是迭代单个项目中的 m 键而不是 n 项目吗?
  • 应该是O(m ^ 2 * n),其中m是键的数量。
  • 感谢您帮助了解这一切:)
【解决方案2】:

让我稍微修改一下你的代码:

items.filter(item => Object.keys(item).forEach(key => console.log("item is", key)));

items 中的每个项目执行 lambda。 lambda 迭代项目中的每个键并打印它。因此,对于 n = 项目数和 m = 每个项目的键数,时间复杂度为 O(n*m)。如果每个项目的键数是固定的并且相对较小,则可以假设 O(n)。大 O 表示法只是对运行时间的粗略估计,常数因子没那么有趣。

【讨论】:

  • 你错过了Object.keys()的复杂性
  • 当我们说“相对较小”时,大致是什么样的?就像我们在哪里画线来考虑 O(n) (或不考虑)?是的还有......正如@pilchard 提到的,我们是否考虑Object.keys()
  • 我猜,这可以忽略不计。调用Object.keys 的复杂度为 O(m),每个项目都调用一次。 forEach 循环也具有 O(m) 的复杂度,并且也为每个项目调用一次。因此,过滤条件的复杂度为 O(2m) = O(m)。
  • @Mohammed 这取决于。在这个例子中,我会说,如果键的数量是恒定的(即项目具有“模式”),但项目的数量是无限的,那么键的数量可以忽略不计。然而,如果键的数量实际上是无限的(没有固定的“模式”),那么 m 也应该被考虑。
  • 注意:我更改代码的原因是在内部循环体内调用Object.keys 是不必要的。每个项目只需要调用一次,这大大降低了复杂性(参见 Mahmoud 的回答)。
猜你喜欢
  • 2014-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-27
  • 2019-05-18
相关资源
最近更新 更多