取最大值和最小值(常數級複雜度)

           最近看到一篇博客登出了一道阿里的筆試題,關於最快的時間複雜度取出一個數組中的最大,以及最小值的問題,所以自己也就思考了下。大部分人的比較次數應該就是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比較下就好。

 

發佈了28 篇原創文章 · 獲贊 5 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章