当前位置: 首页 > 知识库问答 >
问题:

数组中的显著反转

长孙智刚
2023-03-14

我正在研究一个家庭作业问题,以查找整数数组中有效反转的数量。“显著反转”定义如下:

置换[a0,a1,a2,...,an]是其中ai

解决方案需要具有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)

然而,我有合并和计数方法的麻烦。特别是计算显著反转的次数。我修改了我的代码来计算正常的反转次数。

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 += 1
        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:]):
            if(left[i] > 2*right[j-1]):
                count += 1
            result.append(left[i])
            i += 1
        if(right[j:]):
            if(left[i-1] > 2*right[j]):
                count += 1
            result.append(right[j])
            j += 1
    return result, count

所以 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

共有1个答案

聂翼
2023-03-14

您几乎就要成功了,但是还有两个问题:

>

  • 当您找到左[i]的

    您需要将合并过程分为两个阶段,一个用于计算有效反转,另一个用于生成排序输出数组。(在正常反转计数中,这两个将在同一点移动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
    

  •  类似资料:
    • 本文向大家介绍Kafka的一些最显著的应用?相关面试题,主要包含被问及Kafka的一些最显著的应用?时的应答技巧和注意事项,需要的朋友参考一下 答:Netflix,Mozilla,Oracle

    • 本文向大家介绍SQL Server 2016 TempDb里的显著提升,包括了SQL Server 2016 TempDb里的显著提升的使用技巧和注意事项,需要的朋友参考一下 几个星期前,SQL Server 2016的最新CTP版本已经发布了:CTP 2.4(目前已经是CTP 3.0)。关于SQL Server 2016 CTP2.3 的关键特性总结,在此不多说了,具体内容请查相关资料。这个预览

    • 问题 你想要反转数组元素。 解决方案 使用 JavaScript Array 的 reverse() 方法: ["one", "two", "three"].reverse() # => ["three", "two", "one"] 讨论 reverse() 是标准的 JavaScript 方法,别忘了带圆括号。

    • 我使用的是Drools 6,当我在drl中混合了无环和显著性时,我有一种奇怪的行为。 我预计规则将按以下顺序触发:-规则“creation offertransation 4”-规则“creation offertransation 3”-规则“creation offertransation 2”-规则“creation offertransation 1” 然而,当我解雇他们时,我得到了以下顺

    • 数组中的反转是一对索引(i,j),使得a[i] 给定2个数组A和B,我们必须返回这样的对的数目,这样A[i] 例子: 设n=3,A[]=[5,6,7],B[]=[1,2,3],则答案为3。3对为(5,2)、(5,3)和(6,3)。 我的代码: 但这是O(N^2)解。我需要一个更好的解作为N

    • 给定一个1-D数组,比如4个元素5 4 2 3,我知道改进的合并排序(分治)算法可以计算反转数(对,这样我 倒置的编号为4对(5,4) (5,2) (5,3)和(4,3) 我不熟悉堆栈溢出。请原谅格式问题。