題目:有一組數,對於其中任意兩個數字,若前面乙個大於後面乙個數字,則這兩個數字組成乙個逆序對。請設計乙個高效的演算法計算給定陣列中的逆序對個數。
題目分析:
首先要知道什麼是逆序對,比如在陣列[1,2,3,4,5,6,7,0]中,逆序對有:、、、、、、七個逆序對。
方法一:最好想的辦法就是掃瞄整個陣列,每掃瞄到乙個數字的時候,就將這個數字和它後面的數字乙個個進行比較,看是否比它小,比它小這兩個數字就組成乙個逆序對,這個方法的缺點是掃瞄到的每乙個數都要和它後面的每乙個數字比較,時間複雜度為o(n^2),不符合題目要求的高效率。
方法二:採用分治的思想,先分後治,利用歸併排序來求解。
先把長度為4的陣列分解成兩個長度為2的子陣列,再把這兩個子陣列分別拆成兩個長度為1的子陣列。接下來一邊合併相鄰的子陣列,一邊統計逆序對的數目。
1)如果陣列為空null或陣列長度n==0,逆序對數為0;
2)如果陣列不為空,開始分割陣列
3)如果陣列左邊下標不等於右邊下標,分成兩個陣列。定義mid
4)如果陣列左邊下標等於右邊下標,無法再分割,分割結束。(遞迴終止條件)
5)當分割成兩個陣列時,逆序對數=左邊陣列中的逆序對數+右邊陣列中的逆序對數+左右合併成新陣列中的逆序對數
6)在乙個陣列中計算逆序對數時,先定義乙個臨時陣列(用來存放有序的最終陣列)
7)當left>mid+1時,說明left+1,left+2…都》mid+1;
8)返回計數器。
**示例:
public
class
main
return
mergesortsion
(a,0
,n-1);
}public
static
intmergesortsion
(int
a,int l,
int r)
int mid=
(l+r)/2
;return
mergesortsion
(a,l,mid)
+mergesortsion
(a,mid+
1,r)
+merge
(a,l,mid,r);}
public
static
intmerge
(int
a,int left,
int mid,
int right)
else
}while
(i<=mid)
while
(j<=right)
return inversenum;
}}
陣列中逆序對
題目 在陣列中的兩個數字,如果前面的乙個數字大於後面的數字,則這兩個數字為乙個逆序對。輸入乙個陣列,求這個陣列的逆序對個數。例如 給定陣列 則有 5,3 5,1 8,3 8,1 3,1 這5個逆序對。問題分析 我採用兩種方法來解決這個問題 1 考慮到二叉搜尋樹中每個節點x,它的左子樹所有關鍵字的值小...
陣列中的逆序對
來自劍指offer 分析 我們第一反應是順序掃瞄整個陣列,每掃瞄到乙個數字時,逐個比較該數字和它後面的數字的大小。如果後面的數字比它小,則這個兩個數字就組成了乙個逆序對。假設陣列有n個數字,由於每個數字都要和o n 個數字作比較,因此這個演算法的時間複雜度為o n 2 換思路 我們採用歸併思想,先考...
陣列中的逆序對
題目 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。用歸併排序演算法,歸併的時候,從後向前歸併。include using namespace std int getreversenum int p1,int p2,int...