繁体   English   中英

计算列表中的对,使其第一个索引小于第二个但第一个元素大于第二个

[英]Counting the pairs in a list such that their first index is less than the second but the first element is greater than the second

我有清单[5,2,10,9,7]
我想计算所有满足条件的对( i<j and list[i]>list[j] )
例如,索引 5 小于索引 2 但 5 大于 2,因此将计数器增加 1,对于 (10,9) 和 (10,7) 和 (9,7) 相同,因此值计数器将是 4

我已经解决了这个问题,但复杂度为 O(n^2),但我想找到一个时间复杂度最低的解决方案。

这是在 O(n^2) 上运行的代码

 def ques(lista):
     b=0
     for i in range (len(lista)):
        for j in range (1,len(lista)):
            if i<j and lista[i]> lista[j] : 
                b+=1
     return b

Mergesort 应该能够在 O(nlogn) 中做到这一点。 在合并过程中,当我们要合并左右数组时,我们比较arrays的第一个元素,如果右边数组的第一个元素小于左边数组的当前第一个数组,弹出它,添加它到一个新的临时数组。 还将计数器增加左数组的长度(因为左数组中的所有元素都更大但索引更小)。

def mergeSort(a):
    if len(a) >= 2:
        mid = len(a)//2
        left, right = mergeSort(a[:mid]), mergeSort(a[mid:])
        temp = []
        i, j = 0, 0
        for _ in range(len(a)):
            if i < len(left) and j < len(right):
                if  right[j] < left[i]:
                    temp.append(right[j])
                    # here we are counting are our pairs
                    counter[0] += len(left)-i
                    j += 1
                else:
                    temp.append(left[i])
                    i += 1
            elif i < len(left):
                temp.append(left[i])
                i += 1
            else:
                temp.append(right[j])
                j += 1
        return temp
    else:
        return a


counter = [0]
arr = [5, 2, 10, 9, 7]
mergeSort(arr)
print(counter[0])

我不认为它可以在少于 O(n^2) 的时间内完成:

事实上,每个元素都应该与它之后的所有元素进行比较,这意味着对于第一个元素,我们需要:n-1 次比较,对于后面的元素,我们需要 n-2 次比较,依此类推。

(n-1) + (n-2) + (n-3) + ... + 2 + 1 => order of n^2

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM