本文参考其他用快排求逆序数的方法。
在用快排求解逆序数前,我先考虑了这个问题,1:归并和快排的时间复杂度都是nlog(n),为什么不用归并?
我认为应该是由于快排在每次合并时都有用到临时数组,然后每次还需要把临时数组重新copy到原数组中 ,增加了时间复杂度;快排虽然也存在最坏的情况,即n^2,但是由于其随机性,所以期望的时间复杂度仍然是nlog(n),因此如果能用快排求逆序数的话,也是不错的。
本文用快排求逆序数思想:
a[10]={7,1,9,5,6,3,11,2,10,8}
7 | 1 | 9 | 5 | 6 | 3 | 11 | 2 | 10 | 9 |
1 | 5 | 3 | 2 |
|
|
|
| 7 | 9 | 11 | 10 | 9 |
求得逆序数:2500572073
涉及到的 文件,百度网盘 :http://pan.baidu.com/s/1dFxB64T
#!/usr/bin/env python
# coding:utf8
__author__ = 'yangrui'
fp = open('./Q8.txt', 'r')
lines = fp.readlines()
fp.close()
arr = []
for line in lines:
line = line.strip('\n')
arr.append(int(line))
#arr = [7,1,9,5,6,3,11,2,10,8]
count = 0
def SortAndCount(tmp, left, right):
global count
if left == right or right == -1:
return
if right-left == 1:
if tmp[right] < tmp[left]:
count += 1
return
s1 = [];s2 = []
mid = tmp[(right-left)/2]
flag = 0
for i in range((right-left)/2):
if tmp[i] > mid:
count += 1
flag += 1
s2.append(tmp[i])
elif tmp[i] < mid:
count += flag
s1.append(tmp[i])
for i in range((right-left)/2+1, right+1):
if tmp[i] > mid:
s2.append(tmp[i])
flag += 1
elif tmp[i] < mid:
s1.append(tmp[i])
count += 1+flag
SortAndCount(s1, 0, len(s1)-1)
SortAndCount(s2, 0, len(s2)-1)
if __name__ == '__main__':
SortAndCount(arr, 0, len(arr)-1)
print(count)