大O - 总是输入的大小?

时间:2015-10-14 01:39:25

标签: algorithm integer big-o

我制定了自己的面试风格问题,对我解决方案的大问题提出了疑问。我将在下面说明问题和我的解决方案,但首先让我说明显的解决方案涉及嵌套循环并且是O( n 2 )。我相信我找到了一个O( n )解决方案,但后来我意识到它不仅取决于输入的大小,还取决于输入的最大值。看起来我的O( n )的运行时间只是技术性的,并且它可以很容易地在O( n 2 )时间运行在现实生活中更糟糕。

问题是: 对于给定正整数数组中的每个项目,打印数组中所有其他项目是当前项目的倍数。

示例输入:

[2 9 6 8 3]

示例输出:

2: 6 8
9:
6:
8:
3: 9 6

我的解决方案(在C#中):

private static void PrintAllDivisibleBy(int[] arr)
{
    Dictionary<int, bool> dic = new Dictionary<int, bool>();
    if (arr == null || arr.Length < 2)
        return;

    int max = arr[0];
    for(int i=0; i<arr.Length; i++)
    {
        if (arr[i] > max)
            max = arr[i];
        dic[arr[i]] = true;
    }

    for(int i=0; i<arr.Length; i++)
    {
        Console.Write("{0}: ", arr[i]);
        int multiplier = 2;
        while(true)
        {
            int product = multiplier * arr[i];
            if (dic.ContainsKey(product))
                Console.Write("{0} ", product);

            if (product >= max)
                break;
            multiplier++;
        }
        Console.WriteLine();
    }
}

因此,如果两个数组项为1且 n ,其中 n 是数组长度,则内部while循环将运行n次,这相当于O(名词 2 )。但是,由于性能取决于输入值的大小,而不是列表的长度,这使得它成为O( n ),对吗?

您认为这是一个真正的O( n )解决方案吗?是否只有O( n )由于技术性,但在现实生活中较慢?

3 个答案:

答案 0 :(得分:4)

好问题!答案是,不,n并不总是输入的大小:如果没有定义O(n)的含义,你就不能真的谈论n ,但人们经常使用不精确的语言,并暗示n是“在这里扩展的最明显的东西”。从技术上讲,我们通常应该说“这种排序算法在列表中的元素数量中执行O(n)”的比较:“具体说明n是什么,以及我们的数量是多少测量(比较)。

如果你的算法取决于两个不同事物的乘积(这里是列表的长度和其中最大的元素),表达它的正确方式是O(m*n),并且然后为您的上下文定义mn。因此,我们可以说您的算法执行O(m*n)次乘法,其中m是列表的长度,n是列表中的最大项。

答案 1 :(得分:0)

当你必须迭代n个元素并在每次迭代中执行一些恒定时间操作时,算法是O(n)。算法的内部while循环不是恒定时间,因为它取决于数组中最大数字的巨大。

您的算法的最佳案例运行时间是O(n)。当所有n个数字相同时就是这种情况。

你的算法的最坏情况运行时间是O(k * n),其中k =你机器上可能的int的最大值如果你真的坚持在k的值上加上。对于32位int,最大值为2,147,483,647。你可以说这个k是一个常数,但这个常数显然是

  • 对于输入数组的每种情况都不固定;和,
  • 不可忽视。

答案 2 :(得分:0)

  

您认为这是真正的O(n)解决方案吗?

运行时实际上是O(nm),其中marr中的最大元素。如果数组中的元素以常量为界,则可以将算法视为O(n)

你能提高运行时间吗?这是你还能做些什么。首先请注意,您可以确保元素不同。 (您在hashmap中压缩数组,该数组存储在数组中找到元素的次数)。然后你的运行时将是max/a[0]+max/a[1]+max/a[2]+...<= max+max/2+...max/max = O(max log (max))(假设您的数组arr已排序)。如果将此与明显的O(n^2)算法结合使用,则会获得O(min(n^2, max*log(max))算法。