劍指offer:陣列中的逆序對(Python)
阿新 • • 發佈:2019-02-12
題目描述
在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數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