【问题标题】:How do these results prove my method is running in O(n lgn) time?这些结果如何证明我的方法在 O(n lgn) 时间内运行?
【发布时间】:2015-11-15 04:00:26
【问题描述】:

我有一个我在下面写的方法。

public static long nlgn(double[] nums)  {

        long start = System.nanoTime();

        if(nums.length > 1)     {
            int elementsInA1 = nums.length/2;
            int elementsInA2 = nums.length - elementsInA1;
            double[] arr1 = new double[elementsInA1];
            double[] arr2 = new double[elementsInA2];

            for(int i = 0; i < elementsInA1; i++)
            arr1[i] = nums[i];

            for(int i = elementsInA1; i < elementsInA1 + elementsInA2; i++)
            arr2[i - elementsInA1] = nums[i];

            nlgn(arr1);
            nlgn(arr2);

            int i = 0, j = 0, k = 0;

            while(arr1.length != j && arr2.length != k) {
                if(arr1[j] <= arr2[k]) {
                    nums[i] = arr1[j];
                    i++;
                    j++;
                } else {
                    nums[i] = arr2[k];
                    i++;
                    k++;
                }
            }

            while(arr1.length != j) {
                nums[i] = arr1[j];
                i++;
                j++;
            }
            while(arr2.length != k) {
                nums[i] = arr2[k];
                i++;
                k++;
            }
        }

        double max = nums[nums.length - 1];
        double min = nums[0];

        double[] farthestPair = {max, min};

        long end = System.nanoTime();

        return (end - start);
    }

这基本上是一种合并排序操作,一旦排序,就会找到最小和最大的数字。我相信这种方法在 O(n lgn) 时间内运行。但是,当我以每次运行时加倍的输入大小(1000、2000、4000 等)运行该函数时,当我以纳米时间计时时,我会得到以下结果。

First pass: (0.12) seconds
Second pass: (0.98) seconds
Third pass: (0.91) seconds
Fourth pass: (0.90) seconds
Fifth pass: (1.33) seconds

我的问题是,鉴于这些结果,这些结果是否表明此方法在 O(n lgn) 时间内运行?

【问题讨论】:

  • 没错,好吧,我觉得我的措辞有点不对劲。这是正确的,除非通过逻辑,否则我无法证明它。我稍微改变了我的问题的措辞。基本上,我知道双倍输入是否需要大约两倍的运行时间,这表明该方法以线性时间运行。根据我的结果,他们是否建议我的方法在 O(n lgn) 时间内运行?
  • 正如我之前所说,0.12 秒的运行时间太短,无法得出任何结论。增加您的基准大小/重复次数。

标签: algorithm performance sorting runtime big-o


【解决方案1】:

如果你有算法的源代码,你应该分析它而不是做运行时基准测试。

如果是递归函数,请查看master theorem

在您的函数中,您执行 2 次递归调用,大小为 n / 2,因此 a = 2, b = 2f(n) = 2n,因为在您的两个第一个 for 循环中,您遍历所有数组 (n),最后三个 while 循环您再次迭代所有数组大小(n),所以2n

如果你应用主定理,它会给出结果Θ(n ln(n)),所以O(n ln(n)) 也是正确的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-10-23
    • 2015-12-01
    • 2016-01-27
    • 2019-04-20
    • 1970-01-01
    • 2017-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多