面試題36 陣列中的逆序對

2021-07-04 06:42:31 字數 2422 閱讀 5061

題目:在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。例如,有乙個陣列為array[0..n] 其中有元素a[i],a[j].如果 當ia[j],那麼我們就稱(a[i],a[j])為乙個逆序對。在陣列中一共存在5對逆序對,分別是(7,6),(7,5),(7,4),(6,4),(5,4)。
排序演算法

彙總->歸併排序

看到這樣的題目,最簡單的想法就是遍歷每乙個元素,讓其與後面的元素對比,如果大於則count++,但是這樣的時間複雜度是o(n2)。這題有更好的解決方法,時間複雜度只需要o(nlogn)。其實這道題目的思路跟歸併排序差不多,求逆序對的過程就是乙個求歸併排序的過程,在求出逆序對以後,原陣列變得有序,是通過歸併排序得到的。

(1)總體的意思就是將陣列分成兩段,首先求段內的逆序對數量,比如下面兩段**就是求左右兩端陣列段內的逆序對數量

inversions+=inversepairscore(arry,start,mid,temp);//

找左半段的逆序對數目

inversions+=inversepairscore(arry,mid+1,end,temp);//

找右半段的逆序對數目

(2)然後求段間的逆序對數量,如下面的**

inversions+=mergearray(arry,start,mid,end,temp);//

在找完左右半段逆序對以後兩段陣列有序,然後找兩段之間的逆序對。最小的逆序段只有乙個元素。

(3)然後在求段間逆序對的時候,我們分為arry[start...mid]和arry[mid+1...end],然後設定兩個指標ij分別指向兩段陣列的末尾元素,也就是i=mid,j=end。然後比較arry[i]和arry[j],

如果arry[i]>arry[j],因為兩段陣列都是有序的,所以arry[i]>arry[mid+1...j],這些都是逆序對,我們統計出的逆序對為j-(mid+1)+1=j-mid。並且將大數arry[i]放入臨時陣列temp當中,i往前移動

如果arry[i]

#include#include

using

namespace

std;

void printarray(int arry,int

len)

int mergearray(int arry,int start,int mid,int end,int temp)//

陣列的歸併操作

else

}cout

<

呼叫mergearray時的count:

"while(i>=start)//

表示前半段陣列中還有元素未放入臨時陣列

while(j>mid)

//將臨時陣列中的元素寫回到原陣列當中去。

for(i=0;i)

arry[end-i]=temp[i];

printarray(arry,

8);//

輸出進過一次歸併以後的陣列,用於理解整體過程

return

count;

}int inversepairscore(int arry,int start,int end,int

temp)

return

inversions;

}int inversepairs(int arry,int

len)

void

main()

;int arry=;

int len=sizeof(arry)/sizeof(int

);

//printarray(arry,len);

int count=inversepairs(arry,len);

//printarray(arry,len);

//cout

pause");

}

呼叫mergearray時的count:013

7824

65呼叫mergearray時的count:01

3782

465呼叫mergearray時的count:01

3782

465呼叫mergearray時的count:01

3782

465呼叫mergearray時的count:

1//這是因為上面65之間有段內的逆序對13

7824

56呼叫mergearray時的count:01

3782

456呼叫mergearray時的count:

9//這裡全部都是段間的逆序對,(3,2),(7,2),(7,4),(7,5),(7,6),(8,2),(8,4),(8,5),(8,6),一共有九個12

3456

78逆序對數量:

10

面試題36 陣列中的逆序對

1.在陣列中的兩個數字如果前面的乙個數字大於後面的數字,則這兩個數字組成乙個逆序對,輸入乙個陣列,求這個陣列中的逆序對的總數。分析 例如在陣列中,一共存在5個逆序對,常規的做法是每次確定乙個數字在陣列中後面有多少個數比他小,這樣的時間複雜度是o n n 比較大,可以先將大的陣列分為小的陣列,再統計逆...

面試題36 陣列中的逆序對

面試題36 陣列中的逆序對 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。即輸出p 1000000007 輸入描述 題目保證輸入的陣列中沒有的相同的數字 資料範圍 對於 50的...

面試題36 陣列中的逆序對

題目 在陣列中的兩個數字如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。分析 可以利用二路歸併排序演算法對陣列進行排序,並在排序過程中統計逆序對的數目。template void inversepairs vector a,int count ...