大O符号的复杂性

时间:2012-04-10 06:40:10

标签: java big-o

我一直在做一些问题,但没有提供答案,所以我想知道我的答案是否正确

a)假设a [i .... j]是具有n个元素的整数数组,x是整数

int front, back;

while(i <= j) {

    front = (i + j) / 3; 
    back = 2 * (i + j) / 3;

    if(a[front] == x)
        return front;
    if (a[back] ==x)
        return back;

    if(x < a[front])
        j = front - 1;
    else if(x > a[back])
        i = back+1;
    else {
        j = back-1;
        i = front + 1;
    }
}

我的答案是O(1),但我有一种感觉我错了。

B)

public static void whatIs(int n) {
    if (n > 0)
        System.out.print(n+" "+whatIs(n/2)+" "+whatIs(n/2));
}

ans:我不确定它是log4n还是logn,因为递归发生了两次。

3 个答案:

答案 0 :(得分:4)

A)是的。 O(1)错了。您将循环多次,这取决于ijx ...以及数组的内容。计算出最佳最差案例中循环次数。

B)使用log(4*n)(基础高中数学)简化log(a*b) -> log(a) + log(b),然后应用大O的定义。

但这也不是正确的答案。再一次,您应该回到第一原则并计算为参数n的给定值调用方法的次数。并通过归纳进行证明。

答案 1 :(得分:0)

两个答案都不正确。

在每次迭代的第一个示例中,要么找到数字,要么将间隔的长度缩小1/3。即如果过去的长度是n(2/3)* n。最糟糕的情况是你在最后一次迭代中找到x - 当间隔的长度为1.所以就像二进制搜索一样,复杂性是通过日志来计算的:复杂度是O(log 3/2 ( n))这实际上只是O(log(n))

在给定数字n的第二个示例中,执行n / 2所需操作数的两倍。从n = 0和n = 1开始,并使用归纳来证明复杂性实际上是O(n)。

希望这有帮助。

答案 2 :(得分:0)

A)此算法与Golden section search类似。在分析复杂性时,有时候更容易想象如果我们扩展数据结构而不是收缩它会发生什么。可以这样想:每个循环从搜索间隔中删除三分之一。这意味着,如果我们确切地知道一定长度需要多长时间,如果允许再次循环,我们可以增加50% - 指数增长。因此,搜索算法必须具有复杂度O(log n )。

B)每次我们添加一个函数调用的“层”时,我们需要将它们的数量加倍(因为函数总是自己调用两次)。换句话说,给定一定的长度和时间消耗,加倍 n 也需要在最后一层中进行两倍的函数调用。算法是O( n )。