演算法 利用歸併排序快速求取逆序對

2021-10-12 17:41:48 字數 1035 閱讀 8186

逆序對:對於數列的第 i 個和第 j 個元素,如果滿足 i < j 且 a[i] > a[j],則其為乙個逆序對。

如果對歸併排序有疑問,可以看我的另一篇

原理:

由於歸併排序過程中將乙個陣列先一直二分,分為乙個乙個的,然後兩兩合併,比較,較小的先放進另外的陣列,當第乙個陣列的某個值比第二個陣列大時,說明這個元素之後的所有元素都比另乙個陣列中的元素大,也就構成了逆序對。ans+=mid-i+1就是這樣來的。

#include

using

namespace std;

int n;

int temp[

100001];

int a[

100001];

typedef

long

long ll;

ll merge_sort

(int l,

int r)

int mid = l + r >>1;

ll ans =

merge_sort

(l, mid)

+merge_sort

(mid+

1, r)

;int i = l, j = mid +1;

int k =0;

while

(i <= mid && j <= r)

}while

(i <= mid) temp[k++

]= a[i++];

while

(j <= r) temp[k++

]= a[j++];

for(

int i =

0, j = l; j <= r;

++i,

++j)

return ans;

}int

main()

cout <<

merge_sort(0

, n-1)

;return0;

}

利用歸併排序求逆序對

在逆序對的問題中,如果採用暴力求解的方法,一般也是有效的,但是o n2 時間複雜度實在是難以接受的。但是對於逆序對問題,卻有乙個看似不想關的演算法來解決 歸併排序。時間複雜度和空間複雜度完全與歸併排序一樣,只是在歸併過程中,新增了乙個變數,對於逆序對的數目進行了記錄。這樣就將時間複雜度降低到了o n...

逆序對 (歸併排序)

逆序對的nlogn方法,改進後的歸併排序 給定排列p,求排列的逆序對數量。p的長度 100000。要求o nlogn 定義歸併排序過程merge l,r merge l,r merge l,mid merge mid 1,r count l,mid,mid 1,r 只需要考慮左右兩段之間造成的逆序對...

歸併排序 逆序對

按照劉汝佳說的,歸併排序分三步 1.劃分問題,即把序列分成元素盡量相等的兩半 2.遞迴求解 3.合併子問題 其實就是把乙個序列不斷的二分,直到只有兩個元素的時候,然後排序,然後返回,再排序。先上 include using namespace std long long a 100005 t 100...