【问题标题】:Big O analysis of an algorithm - Job Interview算法的大 O 分析 - 工作面试
【发布时间】:2016-11-22 18:21:01
【问题描述】:

最近我有一个面试问题,要编写一个算法来分析数组并返回重复的数字;

我的蛮力解决方案是:

    public static ArrayList getDuplicates  (int[] input){
        ArrayList duplicates =  new ArrayList();
        int marker = 0;
        for (int i = marker + 1; (i < input.length) && (marker < input.length - 1); i++){
            if (input[marker] == input[i]){
                duplicates.add(input[marker]);
                marker++;
                continue;
            } else {
                if (i == input.length - 1){
                    marker++;
                    i = marker;
                }
                continue;
            }
        }
        return duplicates;
    } 

没有深入分析我就回复说大O是n*(log(n))。

面试后我再次检查,发现不是正确答案。

令人困惑的部分是算法重复,但不是重复 n 次,而是每个循环重复 n-k 次,其中 k = {1..n-1}。这是重置移动索引的部分:

                if (i == input.length - 1){
                marker++;
                i = marker;
            }

分析此算法以找到正确的大 O 函数的最佳方法是什么?

【问题讨论】:

  • 每次都给出相同的答案:视情况而定。关于谁在做分析,一方面。这个过程总是终止吗?
  • 在最坏的情况下,时间复杂度似乎是 n^2,因为如果找不到匹配项,您会将每个元素与每个其他元素进行比较。基本上你必须做 input.length 如果没有找到 2 个比较。比较次数以二次方的速度增长。
  • 复制的字典/哈希表会让这对你来说更容易一些,并且会以内存为代价将复杂性降低到 O(n)。
  • 大 O 表示法是关于一般性的——你可以看到这是 > O(n) 所以所有额外的工作都是不值得的——最好做一个 O(n) 解决方案。
  • 你为什么使用ArrayList?它已经过时了快十年了。如果我在进行这次面试,我一看到你的代码就会停止关注你的代码,因为我知道你没有资格。

标签: java algorithm big-o asymptotic-complexity


【解决方案1】:

我分析这个的方法是插入边缘情况,然后看看是否出现任何模式:

  1. 如果您有一个包含所有匹配项的数组会怎样? 在这种情况下,它是 O(N),因为您每次都点击重复项的第一个条目。
  2. 没有重复项怎么办? 然后,你扫描整个数组 N^2/ 2 次,所以 O(N^2)

从这里,我们可以看到你最好的情况是 O(N),更糟糕的是 O(N^2),我还要说平均情况也将是 O(N^2)

如果您使用嵌套 for 循环,一个用于原始数据扫描,一个用于重复扫描,则 N^2 行为会更容易发现。

如果相反,您已将每个条目添加到具有 O(1) 添加能力(哈希表)的容器中,那么您的算法将变得更加简单:

  1. 对于输入数组中的每个项目,尝试将值添加到哈希表。
  2. 如果哈希值已经存在,插入重复数组。
  3. 完成 foreach 扫描并返回重复数组。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-29
    • 2015-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-14
    相关资源
    最近更新 更多