def inversepairs(data):
# write code here
if not data:
return 0
copy =
for i in data:
length = len(data)
count = inversepairscore(data, copy, 0, length - 1)
print(count%1000000007)
return count%1000000007
def inversepairscore(data, copy, start, end):
if start == end:
copy[start] = data[start]
return 0
length = int((end - start) / 2)
left = inversepairscore(copy, data, start, start + length)
right = inversepairscore(copy, data, start + length + 1, end)
i = start + length
j = end
index_copy = end
count = 0
while i >= start and j >= start + length + 1:
if data[i] > data[j]:
copy[index_copy] = data[i]
index_copy -= 1
i -= 1
count += j - start - length
else:
copy[index_copy] = data[j]
index_copy -= 1
j -= 1
copy += data[start:i+1]
copy += data[start + length + 1:j+1]
return (left + right + count)
data = [364, 637, 341, 406, 747, 995, 234, 971, 571, 219, 993, 407, 416, 366, 315, 301, 601, 650, 418, 355, 460, 505, 360, 965, 516, 648, 727, 667, 465, 849, 455, 181, 486, 149, 588, 233, 144, 174, 557, 67, 746, 550, 474, 162, 268, 142, 463, 221, 882, 576, 604, 739, 288, 569, 256, 936, 275, 401, 497, 82, 935, 983, 583, 523, 697, 478, 147, 795, 380, 973, 958, 115, 773, 870, 259, 655, 446, 863, 735, 784, 3, 671, 433, 630, 425, 930, 64, 266, 235, 187, 284, 665, 874, 80, 45, 848, 38, 811, 267, 575]
inversepairs(data)
基本思想:
歸併排序與之前的交換(快速)、選擇(堆)等排序的思想不一樣,「歸併」的含義就是:
將兩個或者兩個以上的有序表組合成乙個新的有序表,假定待排序表含有n個記錄,則可以看做是n個有序的子表,每個子表的長度為1,然後兩兩歸併,得到合併成乙個長度為n的有序表為止,這種排序方法為2-路歸併排序
初始關鍵字: 49 38
65 97
76 1327
一趟歸併後: 38 49 65 97
13 76 27
二趟歸併後: 38 49 65 97 13 27 76
三趟歸併後: 13 27 38 49 65 76 97
merge()的功能是將前後相鄰的兩個有序表歸併成為乙個有序表的演算法。
設兩段有序表a[low,...mid]、a[mid+1,...high]放在同乙個有序表的兩個位置上,先讓它們複製到輔助陣列b裡面,每次從對應b中的兩個段取出乙個記錄進行關鍵字的比較,先將小者放入a中,當陣列b中有一段的下標超出其對應的表長時,即該段所有的元素已經完全複製到a中,另一端中的剩餘部分直接複製到a中。
遞迴形式的2-路歸併排序是基於分治的!過程如下:
**如下:
# merge函式的功能是將前後相鄰的兩個有序子表歸併成為乙個有序表
# left和right就是兩個前後相鄰的有序子表,我們需要乙個輔助陣列result,最後返回的result就是最後的
# 歸併排序結果
# i和j一起從0開始向後走,對應位置(不一定就是下標相同)誰小誰被收到result中去,然後下去的那個指標向
# 後走乙個,直到最後
# 其實result += left[i:] 和 result += right[j:]只會執行乙個,因為有乙個已經被收光了。
def merge(left, right):
i, j = 0, 0
result =
while i < len(left) and j < len(right):
if left[i] <= right[j]:
i += 1
else:
j += 1
result += left[i:]
result += right[j:]
return result
# 遞迴形式的二路歸併演算法是基於分治的
# 分解:將n個記錄一分為2,然後對分開的兩個各含有n/2個元素的子表遞迴呼叫自身
# 合併: 合併兩個已經排序的子表得到結果
def merge_sort(lists):
if len(lists) <= 1:
return lists
num = len(lists) /2
left = merge_sort(lists[:num])
right = merge_sort(lists[num:])
return merge(left, right)
效能:穩定性:
merge不會改變相同關鍵字記錄的相對次序,所以2路歸併排序是乙個穩定的排序演算法。
資料結構 歸併排序
排序 sort 或分類 內部排序方法可以分為五類 插入排序 選擇排序 交換排序 歸併排序和分配排序。歸併排序 include using namespace std 歸併排序中的合併演算法 void merge int a,int left,int center,int len int t int ...
資料結構 歸併排序
歸併排序,即merge sort,通過遞迴式的merge操作 merge即歸併 實現排序。演算法思想是分治思想 divide and conquer 歸併排序一般是遞迴實現的 時間複雜度o nlgn 遞迴都是一去一回,去的時候divide,回的時候conquer。表達欠提煉 1 divide,分 遞...
資料結構 歸併排序!!!
歸併排序 整體思想 將資料分成很多的部分,每次排序資料的一部分,然後將兩部分的資料進行整體排序,這樣一步一步將整體資料排序。如圖 注 將需要排序的資料進行分塊,當每個塊的資料足夠的少的時候就可以進行效率高的排序方法,當兩塊資料排序好的時候就可以將兩塊排序好的資料進行合併。具體實現方法 ifndef ...