阵列中的有效反转

2024-10-01 17:31:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在做一个家庭作业题,要找出一组整数中有意义的倒数。”“显著反转”的定义如下:

A significant inversion in a permutation [a0, a1, a2, ..., an] is one in which ai > 2 aj for some i < j. so for example a = [4,5,2,1,3] has exactly 3 significant inversions, since for this permutation a0 > 2 a3, a1>2 a2, a1 > 2 a3.

解决方案需要具有O(n logn)的复杂性。这需要使用分而治之的方法。我选择实现基于合并排序的解决方案。在

我理解此处给出的拆分操作:

def countInversions(list):
    if(len(list) <= 1):
        return list, 0
    else:
        mid = int(len(list)/2)
        left, a = countInversions(list[:mid])
        right, b = countInversions(list[mid:])
        result, c = mergeAndCount(left, right)
        return result, (a + b + c)

不过,我在使用merge和count方法时遇到了问题。特别是计算显著反转的次数。我修改了我的代码来计算正常的反转次数。在

^{pr2}$

所以print(countInversions([4,5,2,1,3]))应该返回3。但是,它返回1。在

我在找一些关于合并和计数方法的指导。在


最终实施:

def countInversions(list):
    if(len(list) <= 1):
        return list, 0
    else:
        mid = int(len(list)/2)
        left, a = countInversions(list[:mid])
        right, b = countInversions(list[mid:])
        result, c = mergeAndCount(left, right)
        return result, (a + b + c)

def mergeAndCount(left, right):
    result = []
    count = 0
    i,j = 0,0

    while(i < len(left) and j < len(right)):
        if(left[i] > 2*right[j]):
            count += len(left)-i
            j += 1
        else:
            i += 1

    i,j = 0,0
    while(i < len(left) and j < len(right)):
        if(left[i] < right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    result.extend(left[i:])
    result.extend(right[j:])
    return result, count

Tags: 方法rightforlenreturnifdefa1
1条回答
网友
1楼 · 发布于 2024-10-01 17:31:13

你就快到了,但有两个问题:

  1. 当你找到left[i] > 2*right[i]时,你的结论是left[i:]中的所有值都大于2*right[i],因此你应该增加你的计数len(left(i:]),这与len(左)-i相同。(你只是在上面加1,这就是你的值太低的原因。)

  2. 您需要将合并过程分为两个阶段,一个阶段用于计算显著的反转,另一个阶段用于生成已排序的输出数组。(在正常的反转计数中,这两个会在相同的点上移动i和j,因此可以合并,但对于您的情况,这不是真的。)

固定代码:

def mergeAndCount(left, right):
    result = []
    count = 0
    i,j = 0,0

    while(i < len(left) and j < len(right)):
        if(left[i] > 2*right[j]):
            count += len(left)-i
            j += 1
        else:
            i += 1

    i,j = 0,0                
    while(i < len(left) and j < len(right)):
        if(left[i] < right[j]):
            result.append(left[i])
            i += 1
        else:
            result.append(right[j])
            j += 1

    while(left[i:] or right[j:]):
        if(left[i:]):
            result.append(left[i])
            i += 1
        if(right[j:]):
            result.append(right[j])
            j += 1
    return result, count

相关问题 更多 >

    热门问题