我认为这个程序是O(n)运行时是疯了吗?我的TA说它是O(n ^ 2)

时间:2018-02-28 19:29:20

标签: big-o

下面的代码,它应该是O(n)。 有两个循环,我知道这个。但这并不一定意味着它是O(n ^ 2)。函数循环的运行时间不会超过n + 1次(至少据我所知!)。那应该是O(n)。我错了吗?有人可以帮我吗?谢谢!

编辑:程序将奇数整数放在前面,甚至整数放在数组的后面!

public class Main {

public static void main(String[] args) {


    int[] array = new int[]{5, 4, 3, 2, 1, 0};

    organizeArray(array);

    for (int j = 0; j < array.length; j++) {
        System.out.println(array[j]);
    }

}

public static void organizeArray(int[] array) {

    int end = array.length - 1;

    for (int i = 0; i < array.length; i++) {

        int temp = 0;

        while (true) {

            if (i == end)
                break;

            if (array[i] % 2 == 0) {

                temp = array[i];
                array[i] = array[end];
                array[end] = temp;
                end = end - 1;
            }

            if (array[i] % 2 != 0)
                break;

        }

        if (i == end)
            break;

    }

}

}

2 个答案:

答案 0 :(得分:0)

有趣的代码。当i&#39;元素为奇数时,内部for循环将中断。如果它不是奇数,那么它将交换end中的元素,直到找到奇数。由于end在每次交换时递减,并且程序在i到达end时完成,因此iend可以分别在GC.Collect(); GC.WaitForPendingFinalizers(); GC.GetTotalMemory(false) // do not wait for GC 递增/递减大多数O(n)次。因此,并且因为循环中的所有其他操作都是O(1),所以尽管存在嵌套循环,程序确实在时间O(n)中运行。

答案 1 :(得分:0)

由于other question与此版本重复,请允许我在此处发布我的答案。

当您增加i或减少end时,代码为O(n)。在任何情况下,你将其余的工作(n)减少一个。

对于即将到来的作业:您可以通过尝试轻松测试您对big-O的看法。大多数情况下,测试的数量并不需要非常大。这不是证据,但如果你的想法是正确的,它会给你一个很好的暗示。

这是我的100个测试问题的代码。它产生100对数字:数组的长度和循环的数量。您将此列表带到图表中。

public class Main {
    public static void main(String[] args) {
        Main main = new Main();
        Random random = new Random();

        for (int i = 0; i < 100; i++) {
            int[] array = new int[random.nextInt(10000 - 10) + 10]; // between 10 and 9999 numbers long
            for (int j = 0; j < array.length; j++) array[j] = random.nextInt();

            main.organize(array);
        }
    }

    private int[] organize(int[] array) {
        long loops = 0;
        int end = array.length-1;

        // I've shorten your code here. This does the same with less breaks
        for (int i = 0; i < end; i++) {
            while(i < end && array[i] % 2 == 0) {
                swap(array, i, end--);
                loops++;
            }
        }

        System.out.printf("%d\t%d\n", array.length, loops);
        return array;
    }

    private void swap(int[] array, int a, int b) {
        int t = array[a];
        array[a] = array[b];
        array[b] = t;
    }
}

图表看起来像一条直线。所以你的证明应该是O(n),对吧?

O(n) by simply trying out