数组中的逆序对—Python非归并解法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/songyunli1111/article/details/82285007

题目:在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

该问题的最好解法是类似归并排序的解法,时间复杂度为O(nlogn),网上相关介绍博客也很多,这里给出一个非归并解法,复杂度会高一点,但想法非常巧妙,代码非常简易。

以一个例子来说明:

输入数组:data=[3,2,1,5,4,6,0,7]

排序好数组:dataSorted=[0,1,2,3,4,5,6,7]

顺序遍历dataSorted数组,第一个元素0是最小的元素,因此在data数组中,0前面有多少个数,就有多少个逆序对。在0检测完之后,将0从data数组中删除,data=[3,2,1,5,4,6,7],dataSorted数组遍历到1,而1其实就是[1,2,3,4,5,6,7]中的最小元素

因此,原问题就变为子问题:

输入数组:data=[3,2,1,5,4,6,7]

排序好数组:dataSorted=[1,2,3,4,5,6,7]

……

重复上述步骤直到遍历到最后一个元素。

函数代码如下:

def InversePairs(data):
    count = 0
    copy = [i for i in data]
    copy.sort()

    for i in range(len(copy)):
        count += data.index(copy[i])
        data.remove(copy[i])

    return count

注意第三行不能直接copy = data,因为这样是浅复制,他只是将原有的data数组打上一个新标签,所以当其中一个标签被改变的时候,数组就会发生变化,另一个标签也会随之改变。

而用copy = [i for i in data]相当于深复制,即将原数组重新复制一份给copy,两者就不会相互影响了,但需要多一份数组的内存空间,而浅复制不会重新占用空间。

复杂度分析:

sort排序复杂度为O(nlogn);单次index查找复杂度为O(lgn),要查找n次,复杂度也为O(nlogn);单次remove操作中:查找该数的复杂度为O(lgn),移动该数后面的数复杂度为O(n),因此复杂度为O(n),要remove操作n次,复杂度为O(n^2);因此总的复杂度为O(n^2)。

猜你喜欢

转载自blog.csdn.net/songyunli1111/article/details/82285007