算法的大O分析 - 工作面试

时间:2016-11-22 18:21:01

标签: java algorithm big-o asymptotic-complexity

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

我的蛮力解决方案是:

    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;
            }

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

1 个答案:

答案 0 :(得分:1)

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

  1. 如果你有一系列所有比赛会怎么样? 在这种情况下,它是O(N),因为您每次都会点击重复项的第一个条目。
  2. 没有重复怎么办? 然后,你通过整个阵列扫描N ^ 2/2次,所以O(N ^ 2)
  3. 由此,我们可以看出你最好的情况是O(N),更糟的是O(N ^ 2),我也会说平均情况也是O(N ^ 2)

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

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

    1. 输入数组中的Foreach项,尝试向哈希表添加值。
    2. 如果该值已存在于哈希中,请插入重复数组。
    3. 完成foreach扫描并返回重复数组。