为什么即使我只使用一个循环,时间复杂度也有所不同?

时间:2018-12-28 22:02:36

标签: python python-3.x performance time-complexity

我正在解决CodeLab上的一个问题,该问题要求删除重复项,以便每个元素最多可以出现两次并返回新的长度。

给出输入数组A = [1,1,1,2] 您的函数应返回length = 3,并且A现在为[1,1,2]

我的Python代码可以正常运行,并且是正确的,但是它表示运行时间(时间复杂度)太长。但是,当我运行类似的Java代码(一个循环)时,它会接受它。我在Python代码中做错什么了,以至于时间太多了?

def removeDuplicates(A):
    if len(A) <= 2:
        return len(A)
    i = 0
    n = len(A)
    while i < n:
        if i <= len(A)-3:
            if A[i] == A[i+1] and A[i] == A[i+2]:
                del A[i]
                i -= 1
        i += 1
    return i

Java代码:

public int removeDuplicates(ArrayList<Integer> a) {
    int count = 1;
    int shiftLeft = 0;
    int i = 1;
    while (i < a.size()){
        a.set(i-shiftLeft, a.get(i));
        if (a.get(i-1-shiftLeft).equals(a.get(i))){
            count ++;
        }
        else {
            count = 1;
        }
        if (count == 3){
            shiftLeft ++;
            count --;
        }
        i ++;
    }
    for (int j=0; j<shiftLeft; j++){
        a.remove(a.size()-1);
    }
    return a.size();
}

1 个答案:

答案 0 :(得分:1)

从给定索引的数组中删除需要线性时间。这是因为您必须将所有元素向右移一个空格,这也需要O(n)。

您可以使用以下技巧在固定时间内进行删除。首先将要删除的元素交换到数组的末尾,然后使用pop()将数组大小减小一个元素。

尽管无法对数组进行排序,但您仍无法实现这样的通用删除,因为它可能仍具有某些需要保留的特定顺序。


回到问题:您将不得不进行就地实现约束,没有额外的空间,只有一个循环。也就是说,这是我现在能想到的最好的方法:

l = [1, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6]

def removeDuplicates(l):
    for i in range(len(l) - 1, 0, -1): 
        if (l[:i]).count(l[i]) >= 2:
            del l[i]
    return(l)

print(removeDuplicates(A)) #=> 8
print(l) #=> [1, 2, 3, 4, 4, 5, 5, 6]