通过移动元素去除重复的复杂性

时间:2016-05-12 21:51:51

标签: time-complexity big-o

以下代码试图通过覆盖重复的元素来从排序的数组中删除重复项。虽然它嵌套了for循环,但它的复杂性肯定小于O(n ^ 2)。以下代码的复杂性是什么?

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

        if(arr[i]==arr[i+1]){
            for(int j=i+1;j<n-1;j++){
                arr[j]=arr[j+1];
            }
            n--; i--; 
        }   
    }

1 个答案:

答案 0 :(得分:1)

让我们从第一个位置开始。它肯定不会重复,所以你不做任何动作。然后我们进入第二个位置。它可以从第一个位置值复制,然后,它可能不是。如果是,那么你必须将它移动到最后,因此,对于前两个位置,你有两个场景,一个只是通过数组移动(它不重复),第二个是移动元素到数组的末尾,需要n-2的{​​{1}}次操作。

现在,如果我们将第三个值移到第二个位置,我们仍然在它上面(arr[j]=arr[j+1]部分)。它可以是第一个值的副本,也许不是。对于第一个选项,您必须执行i--(因为您执行了n-3,因此您将其从位置n--移动到位置2n-1的操作。现在,如果第二个值不是第一个值的重复(所以你没有arr[j]=arr[j+1]i--),但第三个值是前两个值之一的重复,你仍然需要做{{ 1}} n--的操作(从位置n-3到位置arr[j]=arr[j+1])。因此,每种情况下的操作次数保持不变。

所以,我们在这里有一个模式:动态的3。这笔款项是:

n

基于此,由于第一部分正在通过数组移动,即n-2 + n-3 + n -4 + ... + 3 + 2 + 1,因此该算法的复杂度为n-2 + n-3 + n -4 + ... + 3 + 2 + 1 = n(n+1)/2 - n - n + 1 。最糟糕的情况是在数组中具有所有相同的值。

现在,有一种更好的方法。将所有值都放在O(n)中。这需要移动数组(O(n^2)),并检查Set中是否存在某些内容,即Set。然后从O(n)获取所有结果,并将它们放在数组中,即O(1)。因此,此类算法的复杂性为Set