首先闡述一下逆序對的概念。假設有乙個陣列為array[0..n] 其中有元素a[i],a[j].如果 當ia[j],那麼我們就稱(a[i],a[j])為乙個逆序對。
那麼統計乙個陣列中的逆序對,有什麼作用呢。逆序對可以反映插入排序的效率問題,如果逆序對數量多,那麼插入排序的效率就低,反之亦然。
那麼如何快速的找到逆序對的數量,同時又能夠對陣列進行排序,並且使得複雜度為o(n*logn)呢?這就可能是乙個小問題
看到複雜度為n*logn 有一種親切感,應為我們可以知道歸併排序的時間複雜度為o(n*logn)。 同時歸併排序是通過遞迴的方法建立遞迴樹,利用最小的兩個元素進行對比然後逐層向上進行遞迴,然後對比兩個已經排好序的陣列,得到最終完整的排好序的陣列。
歸併排序分為了3步驟;
第一步 拆分
第二步進行 計算兩個同樣型別但是規模較小的陣列
第三步 合併兩個已排好序的陣列
因此從整個陣列拆分過程中,我們將它不斷進行拆分,而拆分得到的兩個陣列,又是和原陣列目的和形式相同的(即都是要排序,同時如果不為最小還要進行以上3步)
這樣可以想到遞迴解決問題,每一層進行相同的3步,知道不能進行位置。那麼這個不能進行的判斷顯得格外重要。
那麼加入了逆序對後,如何考慮呢,實際上很簡單。以為從最下面的含兩個元素的陣列,到上層含多個元素的陣列都有前後之分,這正好與逆序對性質相符,只要我們找出前面那乙個陣列中假設l[i] 大於 後面乙個陣列中某個元素r[j] 然後就知道前面那個陣列在該元素l[i]之後的元素都應該是大於r[j]的。因為在歸併過程我們也進行了排序。
大概思路就是這樣,以下是**。
#include "stdafx.h"
#include "stdio.h"
#include "stdlib.h"
#define infinite_num 1000
int l[100];
int r[100];
int merge_sort(int array,int p,int q,int r)
if(l[i]<=r[j])
else
}return inversions;
}int merge_inverse(int array,int p,int r)
return inversions;
}int main(int argc, char* argv)
; int inverse_times = 0;
inverse_times = merge_inverse(array,0,7);
printf("%d",inverse_times);
return 0;
}
統計陣列的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。題目 思路 這個最簡單的當然是直接統計了,演算法時間複雜度為n 2,氣泡排序都可以。如果想進一步減少時間複雜度的話,可以考慮用遞迴的方法,比如使用歸併排序。下面貼 i...
陣列中逆序對
題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...
LeetCode 統計陣列中逆序對的個數
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對.輸入乙個陣列,求出這個陣列中 的逆序對的總數p.並將p對1000000007取模的結果輸出.即輸出p 1000000007.note 2 n 50000 example 1 input nums 9,6,8,5...