题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
解题思路
- 这道题在牛客网上,有Python编写正经的解法,会一直提示运行超时。用Java编写时可以通过。
- 一般的解题思路可以是直接一个一个比较,但这样比较Low。无视之。
更好一点的是拷贝该数组后对拷贝的数组排序。计算数组中的最小值在原始数组中出现的位置,统计原始数组中最小值前面的个数,之后在原始数组中去掉最小值。重复上述步骤。
代码如下:
def InversePairs(self, data):
sortData = sorted(data)
count = 0
for i in sortData:
pos = data.index(i)
count += pos
data.pop(pos)
return count
def quick_sort(self, data):
if len(data) < 2:
return data
left = self.quick_sort([i for i in data[1:] if i <= data[0]])
right = self.quick_sort([j for j in data[1:] if j > data[0]])
return left + [data[0]] + right
第二种思路:
归并排序的改进版,把数据分成前后两个数组(递归分到每个数组仅有一个数据项)。合并数组,合并时,出现前面的数组值array[i]
大于后面数组值array[j
]时;则前面数组array[i]~array[mid]
都是大于array[j]
的,count += mid+1 - i
。这个思路来自牛客网中的一位。用Java实现可以通过;但转成原样Python后超时。
代码如下:
import time
import copy
class Solution:
def InversePairs(self, array):
if not array:
return 0
arrCopy = copy.deepcopy(array)
return self.InverseRecur(array, arrCopy, 0, len(array)-1)
def InverseRecur(self, array, arrCopy, start, end):
if start == end:
return 0
mid = (start + end) // 2
left = self.InverseRecur(array, arrCopy, start, mid)
right = self.InverseRecur(array, arrCopy, mid+1, end)
count = 0
i = mid
j = end
locCopy = end
while i>=start and j > mid:
if array[i] > array[j]:
count += j - mid
arrCopy[locCopy] = array[i]
locCopy -= 1
i -= 1
else:
arrCopy[locCopy] = array[i]
locCopy -= 1
i -= 1
while i >= start:
arrCopy[locCopy] = array[i]
locCopy -= 1
i -= 1
while j > mid:
arrCopy[locCopy] = array[j]
locCopy -= 1
j -= 1
s = start
while s <= end:
array[s] = arrCopy[s]
s += 1
return left + right + count