劍指offer 陣列中的逆序對

2021-08-19 11:33:39 字數 1409 閱讀 2005

題目描述

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數p。並將p對1000000007取模的結果輸出。 即輸出p%1000000007

思路:遇到該問題的時候,最直觀的方法是用兩個for迴圈進行求解,複雜度為o(

n2) 。理所當然的超時了。

然後思考其他解決方法,看能不能利用已經遍歷比較過的資訊,進行求解。先考慮從前往後遍歷,然後發現很難利用已經計算出來的結果

因此考慮從後往前的遍歷,考慮當前判斷數字ar

ray[

inde

x1] 的逆序對數目,那麼我們需要找到該數在in

dex1

到ind

exen

d 的位置,從而得到在該位置之前的數字個數。那麼理所當然的,我們希望在in

dex1

之後的陣列是有序的。但是這樣仍然不能夠顯著降低複雜度,複雜度仍然是o(

n2) , 原因是什麼呢?

原因在於in

dex1

之前的一部分陣列仍然是無序的,因此每次我們都要從後面已經有序的陣列從頭遍歷。因此如果從in

dex0

,ind

ex1 該段的陣列是有序的呢? 那麼我們就可以不必要每次都要從後面的陣列從頭遍歷了。

到這裡我們遇到了新的問題,就是怎麼保證部分陣列有序?而且在保證有序的過程中,怎麼計算其中的逆序對數?

在這裡我們想到了這個問題和歸併排序很像,因此我們考慮用歸併排序來解決。

code:

class solution 

long

long guibing(vector

&data, vector

&aux,int start, int end)

int length = (end-start)/2;

long

long left = guibing(data,aux,start,start+length);

long

long right = guibing(data,aux,start+length+1,end);

int i = start+length;

int j = end;

long

long count =0;

int indexc = end;

while(i>=start&&j>=start+length+1)

else

}while(i>=start)

while(j>=start+length+1)

i=start;

while(i<=end)

data[i++]= aux[i++];

return count + left+right;

}};

劍指offer 陣列中的逆序對

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。解法一 乙個數字能不能構成逆序對,關鍵看後面有幾個比他小的數字。根據這個思路,我們可以從後向前遍歷整個陣列。並用乙個大小為10的陣列,分別來儲存從後向前遍歷陣列時0 9每個數字...

劍指offer 陣列中的逆序對

題目描述 在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。class solution vector tmp len int res mergesort data,tmp,0,len 1 return res private...

劍指offer 陣列中的逆序對

在陣列中的兩個數字,如果前面乙個數字大於後面的數字,則這兩個數字組成乙個逆序對。輸入乙個陣列,求出這個陣列中的逆序對的總數。分析 類似於mergesort的思想,對於兩個排序的陣列,用兩個指標分別指向末尾,比如p,q,如果p的值大於q,那麼p與q和q之前所有數字都可以組成逆序對,count就加上後乙...