【算法導論】第三版課後習題2-4逆序對

網上有關這題的解答很多,比如:http://blog.csdn.net/qcgrxx/article/details/8005221 講的很詳細了。

有關逆序對的題目:http://www.cppblog.com/ickchen2/articles/62422.html

但是在最後一問中關於怎樣求一個排列中逆序對的個數的問題上,我雖然知道網上很多修改歸併排序O(nlgn)的算法可以求解,但是我還有另外一個用堆棧O(n)的方法,我自認爲是正確的,但是被某判卷是錯誤的,很是鬱悶,下面我把主要過程記下來,希望各位大俠能幫忙指正。

比如算法導論上的例子,數組a爲<2,3,8,6,1>有5個逆序對,分別爲(2,1), (3,1), (8,6), (8,1), (6,1)。

那麼我可以這樣做,使用堆棧數據結構,堆棧中存放的是數對(x,y), 其中x爲數組a中的元素,y爲數組中以x開頭可以形成的逆序對的個數。初始時堆棧爲空,逆序對個數爲ans=0,從右向左掃描數組,如下:

1. 因爲第一個元素爲1,不能形成逆序對,所以將(1,0)壓入棧。

2. 因爲6比棧頂元素1大,所以可以形成(6,1)這一個逆序對,又因爲1對應的逆序對是0個,所以6對應的逆序對是0++即1個;所以將(6,1)壓棧,ans++爲1.

3. 因爲8比棧頂元素6大,所以可以形成(8,6)這一個逆序對,既然8和6可以形成逆序對,那麼8可以和以6開頭的元素都形成逆序對,即8可以形成1++=2個逆序對;所以將(8,2)壓棧,ans+=2爲3.

4. 因爲3比棧頂元素8小,所以(8,2)彈棧。

5. 因爲3比棧頂元素6小,所以(6,1)彈棧。

6. 因爲3比棧頂元素1大,此時的棧頂爲(x,y)=(1,0),所以可以形成y++=1個逆序對,將(3,1)壓棧,ans+=1爲4.

7. 因爲2比棧頂元素3小,所以(3,1)彈棧。

8. 因爲2比棧頂元素1大,所以可以形成y++=0++=1個逆序對,將(2,1)壓棧,ans+=1爲5.

9. 所有元素都已經測試過了,最終ans爲5即爲逆序對的個數。


因爲以上算法只要遍歷一遍數組即可,所以時間複雜度爲O(n)。

我覺得以上思路合情合理,不知道哪裏有錯誤,求各位指點!


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章