劍指Offer(35) 陣列中的逆序對

2021-09-14 08:26:29 字數 2563 閱讀 4649

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數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...