陣列中的逆序對(分治)

2022-07-12 10:18:11 字數 1177 閱讀 2065

題目描述:

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。

輸入:

每個測試案例包括兩行:

第一行包含乙個整數n,表示陣列中的元素個數。其中1 <= n <= 10^5。

第二行包含n個整數,每個陣列均為int型別。

輸出:

對應每個測試案例,輸出乙個整數,表示陣列中的逆序對的總數。

樣例輸入:

4

7 5 6 4

樣例輸出:

5

1.直接的做法是逐個統計,複雜度是n^2,

2.可以利用歸併排序的思想,在排序過程中統計逆序對的個數。時間複雜度依然是 n*log(n)。 可以從**中看到,只是比歸併排序多了一句**:cnt += (n1 - i);

由於最終個數可能超過int,這裡用long long

1 #include 2 #include 3 #include 4

using

namespace

std;56

long

long mergeandcount(int arr, int l, int m, int

r)15

for(i = 0; i < n2; i++)

18 i = 0

; 19 j = 0

;20 k =l;

21//

從小到大排序

22while(i < n1 && j 31 k++;32}

3334

while(i 3839

while(j 4344

return

cnt;

4546}47

48long

long mergesortandcount(int arr, int l, int

r)58

return cnt1 + cnt2 +cnt3;59}

6061

intmain()

逆序對 分治nlogn

定義 a是包含n個元素的有序序列 a1,a2 an 若ai aj 且 i j 則稱 ai aj 是a的乙個逆序對。求逆序對是指求出a中存在逆序對的數量。這個演算法是歸併排序的演化,僅需加上一行,就可以求逆序對個數。簡單的概括是 在把兩個子串行合併時 兩個子串行已經有序 如果當前選的最小的數在後面那個...

陣列中的逆序對 分治法(歸併排序的應用)

題目描述 輸入乙個陣列,求陣列中逆序對的總數 高效解法 採用分治法,步驟上與歸併排序一模一樣 例 和產生1個逆序對 7,5 按從小到大合併為 和產生1個逆序對 6,4 按從小到大合併為 以和說明merge函式的流程 綜上共有5個逆序對 merge函式 int merge int p,int q,in...

統計逆序對的個數,並輸出具體的逆序對(分治演算法)

要求 借鑑歸併排序的演算法,在歸併的過程中,統計逆序對的個數,並記錄下具體的逆序對。設計乙個分治演算法,並用c c 語言實現程式設計。include stdio.h int count 0 void merge int r,int r1,int s,int m,int t 合併子串行 else r1...