最近看到一篇博客登出了一道阿里的筆試題,關於最快的時間複雜度取出一個數組中的最大,以及最小值的問題,所以自己也就思考了下。大部分人的比較次數應該就是2N了。我想的這個算法思想,好像還有好一點,所以就貼出來,供大家看看。如果思路出問題了,煩請各位指出來。
給出示例數組:4 1 5 9 9 7 10 2 (N = 8)
思想大概是這樣的:
1 . 比較1 和 N , 2 和 N-1 ...繼續下去, 如果左邊的比右邊的大就互換。局部性上, 就會呈現左邊的部分裏必定有最小值,而右邊的也絕對保存了最大值。
第一輪過後就成了: 2 1 5 9 ~ 9 7 10 4
2 . 在分開的左右部分中各自尋找最小值與最大值
第二輪過後就成了: 2 1 ~ 5 9 ~~4 7 ~ 9 10 (紫色爲無需比較的部分)
3 . 這樣左邊部分又被劃分成左邊的左邊部分, 右邊的右邊部分
第三輪過後就成了: 1 ~ 2 ~~ 5 9 ~~~ 4 7 ~~ 9 ~ 10
這樣三輪過後就找出了最小值與最大值了。
數學分析比較次數(對於單邊):
第1次比較的次數就是N/2^2 (數組比較長度爲N/2, 再次對半)
.......
第n次比較的次數就是 N/2^k (N/2^k=1的)
N/2^k = 1 的最後一次比較。所以針對於左半邊的次數就是
(N/2^2 + N/2^3 + ....+ N/2^k)
總的比較次數就是: N/2 + 2(N/2^2 +N/2^3 + .... + N/2^k) = 3N/2 - 2
時間複雜度爲常數了!(正對於奇數個數組個數,只要在最後將數組的中間位和a[0] 或者 和 a[N-1]比較即可),
代碼我就不寫了,大夥有興趣自己寫寫吧,不難。
算法流程:
如果是偶數個數的: 直接對半,比較即可,例如: 4 1 2 5 3 6 8 4 => 4 1 2 5 | 3 6 8 4
如果是奇數個數的: 先拋棄中間那個,再比較,例如: 4 1 2 5 3 6 8 4 10 => 4 1 2 5 | 3 | 6 8 4 10 最後再跟3比較下就好。