用分而治之的方法检查重复项

时间:2015-03-26 16:29:35

标签: algorithm python-3.x mergesort divide-and-conquer

要在nlogn中搜索重复项,我决定使用修改的合并排序。 主要问题是出现错误,我不知道如何解决这个问题:结果有时是完全错误的。

如果找到一对(具有相同值的元素),我的算法必须返回True,如果没有一对,则返回False。所有这一切都必须在分而治之的算法中完成。(没有额外的循环ecc。)

这是代码

def check_duplicates(X):   
    if len(X)>1:
        mid = len(X)//2
        lefthalf = X[:mid]
        righthalf = X[mid:]

        check_duplicates(lefthalf)
        check_duplicates(righthalf)

        i=0
        j=0
        k=0
        while i<len(lefthalf) and j<len(righthalf):
            if lefthalf[i] == righthalf[j]:
                return True

            if lefthalf[i]<righthalf[j]:
                X[k]=lefthalf[i]
                i=i+1
            else:
                X[k]=righthalf[j]
                j=j+1
            k=k+1

        while i<len(lefthalf):
            X[k]=lefthalf[i]
            i=i+1
            k=k+1

        while j<len(righthalf):
            X[k]=righthalf[j]
            j=j+1
            k=k+1

   return False

我们举一些例子: 让X=[1,2,3]函数返回false,没关系。 让X=[1,3,2]函数返回false,这也没问题。

主要问题在于这种情况:

X=[1,3,3]函数返回false,这是错误的(应该返回true)。

X=[4,6,6]函数返回false,这是错误的等等。

主要问题是当我在列表的末尾添加两个相同的值时,我不知道如何修复它...

ps:我为我的英语道歉

1 个答案:

答案 0 :(得分:1)

您忘记了如果您执行递归调用,并且调用结果为True,则也会返回True:因此,请将递归调用修改为:

if(check_duplicates(lefthalf)) :
    return True

或完整(缩进)版本读取:

def check_duplicates(X):   
    if len(X)>1:
        mid = len(X)//2
        lefthalf = X[:mid]
        righthalf = X[mid:]
        if(check_duplicates(lefthalf)) :
            return True
        if(check_duplicates(righthalf)) :
            return True
        i=0
        j=0
        k=0
        while i<len(lefthalf) and j<len(righthalf) :
            if lefthalf[i] == righthalf[j]:
                return True
            if lefthalf[i]<righthalf[j]:
                X[k]=lefthalf[i]
                i=i+1
            else:
                X[k]=righthalf[j]
                j=j+1
            k=k+1

        while i<len(lefthalf):
            X[k]=lefthalf[i]
            i=i+1
            k=k+1

        while j<len(righthalf):
            X[k]=righthalf[j]
            j=j+1
            k=k+1

    return False

在while循环中,您只检查交叉相等(两个子列表中的相等元素)。但是只有在最高级别比较return True时,才会返回您的版本中的结果。

换句话说,忘记在调用堆栈中传播True值。