在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。 即輸出p%1000000007。例如輸入,輸出5對。
分治思想,採用歸併排序的思路來處理。在合併兩個有序序列時,同時計算逆序對數。
對於兩個公升序序列,設定兩個下標:兩個有序序列的末尾。
每次比較兩個末尾值,如果前末尾大於後末尾值,則有「後末尾指標減中間值」個逆序對,並移動後末尾指標;否則不構成逆序對,向前移動前末尾指標。然後把較大值拷貝到輔助陣列(即合併完的公升序序列)的末尾。每次在合併前,先遞迴地處理左半段、右半段,則左、右半段有序,且左右半段的逆序對數量可得,再計算左右半段合併時逆序對的個數。
逆序對的總數=左邊陣列中的逆序對的數量+右邊陣列中逆序對的數量+左右結合成新的順序陣列時出現的逆序對數量。
例如:陣列:分成左右兩部分 再分
再分然後一邊歸併排序一邊計數
第一步:
一對逆序對,排序後變成
零對逆序對,排序後不變仍舊是
一對逆序對,排序後變成
零對逆序對,排序後不變仍舊是
第二步:(只比較前後兩個之間,不比較內部,因為上一步已經比較完內部)
零對逆序對,排序後不變仍舊是
兩對逆序對(和),排序後變成
第三步:
指標:i->8,j->4。8>4,則8>1、2、3,計數加入j-mid(7-3=4),i指標向前移動。
指標:i->7,j->4。7>4,則7>1、2、3,計數加入j-mid(7-3=4),i指標向前移動。
…直至i移動到head。
另一種情況:
指標:i->8,j->9。8<9,j指標向前移動。
指標:i->8,j->5。8>5,則8>2、4,計數加入j-mid(6-3=3),i指標向前移動。
指標:i->7,j->5。7>5,則7>2、4,計數加入j-mid(6-3=3),i指標向前移動。
指標:i->3,j->5。3<5,j指標向前移動。
…直至j移動到mid或者i移動到head。
public
class
solution
int[
] copy =
newint
[array.length]
;for
(int i =
0; i < array.length; i++
)int count =
inversepairscore
(array, copy,
0, array.length -1)
;return count;
}private
static
intinversepairscore
(int
array,
int[
] copy,
int head,
int tail)
// mid的位置
int mid =
(head + tail)
>>1;
// 遞迴,分別計算左邊和右邊內部的逆序對個數
int leftcount =
inversepairscore
(array, copy, head, mid)
%1000000007
;int rightcount =
inversepairscore
(array, copy, mid +
1, tail)
%1000000007
;// count計數左右兩者之間的對數
int count =0;
// i指向mid,j指向tail
int i = mid;
int j = tail;
// 臨時陣列的指標,指向tail
int tempcopy = tail;
while
(i >= head && j > mid)
// 如果arr[i]小於arr[j],tempcopy和j都向前移動
}else
}// 移動完之後將沒存放的數字存入臨時陣列,例如[1,2,3,4][5,6,7,8],
// 臨時陣列存完後面四個[5,6,7,8],j移動到mid移動終止,將剩下的[1,2,3,4]存入臨時陣列
for(
; i >= head; i--
)// 同理,這也是移動完之後將沒存放的數字存入臨時陣列,例如[5,6,7,8][1,2,3,4],
// 臨時陣列存完後面四個[5,6,7,8],i移動到head移動終止,將剩下的[1,2,3,4]存入臨時陣列
for(
; j > mid; j--
)// 將臨時陣列複製到原陣列,以便遞迴
system.
arraycopy
(copy, head, array, head, tail - head +1)
;return
(leftcount + rightcount + count)
%1000000007;}
}
劍指offer35 陣列中的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字 資料範圍 對於 50的資料,size 1...
劍指Offer 35 陣列中的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字 資料範圍 對於 50的資料,size 1...
劍指Offer 35 陣列中的逆序對
題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字資料範圍 對於 50的資料,size 10...