嵌套for循环总是O(n ^ 2)?

时间:2017-10-09 22:29:18

标签: algorithm big-o

我正在努力想出这个代码的复杂性(这不是一个家庭作业问题,我只是想了解这个概念):

public static boolean boxesHaveItem(List<Box> boxes, Item object) {
    for (Box box : boxes) {
        for (Item item : box.getItems()) {
            if (item.equals(object)) {
                return true;
            }
        }
    }
    return false;
}

因为有嵌套for循环,你的instict将是O(n ^ 2),但这没有意义,因为盒子中的项目数量与盒子的数量无关。传递给这种方法。

也许O(mn),其中m =盒子中的平均物品数量,n =盒子数量?

我认为O(n)是最好的,其中n是传递给函数的所有框中的项目总数,但这有点奇怪,因为它们没有直接传递给功能。

1 个答案:

答案 0 :(得分:6)

这里有多个选择。在谈论复杂性时,您应该为受众选择有用的依赖关系。

该方法明显取决于项目的数量,它会产生Theta(|items|)。因此,如果n是项目数量,那么您有Theta(n),这绝对是正确的。

如果项目与方框之间存在依赖关系,例如一个盒子最多可以包含5个项目,那么你也可以根据盒子的数量来表达复杂性。然后它显然也会产生Theta(|boxes|)

如果没有依赖,那么无法表达框的数量的复杂性,因为不依赖于它

只需选择最适合您的观众的任何内容。

“嵌套for循环总是O(n ^ 2)?”

对于你的另一个问题,答案是否定的。它们并不总是O(n^2)。您可以轻松地创建一种情况,其中一个循环影响另一个循环的迭代,从而产生不同的复杂性。

一个小的构造示例:

for (int i = 0; i < n; i++) {
    for (int j = i; j < i + 5 && j < amount; j++) {
        ...
    }
}

乍一看,循环可能看起来像O(n^2),但内循环最大限度地为外循环的每次迭代创建 5次迭代。因此,我们总共只收到5 * n次迭代,而不是n^2。因此,复杂性为O(n)