1. 程式人生 > >劍指offer:陣列中的逆序對(Python)

劍指offer:陣列中的逆序對(Python)

題目描述

在陣列中的兩個數字,如果前面一個數字大於後面的數字,則這兩個數字組成一個逆序對。輸入一個數組,求出這個陣列中的逆序對的總數P。並將P對1000000007取模的結果輸出。 即輸出P%1000000007

解題思路

  1. 這道題在牛客網上,有Python編寫正經的解法,會一直提示執行超時。用Java編寫時可以通過。
  2. 一般的解題思路可以是直接一個一個比較,但這樣比較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