找陣列的波谷;及巧妙排序的分析
今日面試題:找陣列的波谷
一個陣列A[1...n],滿足A[1]>=A[2], A[n] >= A[n-1]。A[i]被成為波谷,意味著:A[i-1] >= A[i] <= A[i+1]。請給出一個演算法,找到陣列中的一個波谷。O(n)的方法,是很直接,有更快的方法麼?
=========================
巧妙排序分析:
原題
排序只有1,2,3三個元素的陣列,不能統計1,2,3的個數。
分析
這個題目,儘管也是排序,但卻不能使用快速排序的方法。只有三個元素,如果時間複雜度仍舊是O(nlogn),顯然不是最好的。那就可以使用線性的排序演算法,例如計數排序,可是題目中要求,不能夠對1,2,3進行統計個數。那該如何處理呢?請大家看下面的方法,我們首先通過例子來說明:
2 | 1 | 1 | 3 | 3 | 2 |
p1 | p2 | p3 |
假設,我們有三個指標:p1、p2、p3.p1從左側開始,指向第一個非1的數字;p3從右側開始,指向第一個非3的數字。p2從p1開始遍歷,如果是2,p2繼續遍歷,直到p2遇到1或者3:
如果遇到1,則和p1進行交換,然後p1向右,指向第一個非1的數字
如果遇到3,則和p3進行交換,然後p3向左,指向第一個非3的數字
1 | 2 | 1 | 3 | 3 | 2 |
p1,p2 | p3 | ||||
交換之後,p2繼續從p1開始,如果是2繼續遍歷,如果是1或者3,重複上面的步驟,所得如下:
1 | 1 | 2 | 3 | 3 | 2 |
p1,p2 | p3 |
根據上面的方法繼續下去
1 | 1 | 2 | 2 | 3 | 3 |
p1 | p3 | p2 | |||
p2在p3右側,演算法結束。
總結一下上面的演算法:
p1從左側開始,指向第一個非1的數字;p3從右側開始,指向第一個非3的數字。
p2從p1開始遍歷,如果是2,p2繼續遍歷,直到p2遇到1或者3
如果遇到1,則和p1進行交換,然後p1向右,指向第一個非1的數字
如果遇到3,則和p3進行交換,然後p3向左,指向第一個非3的數字
重複上面的步驟,直到p2在p3的右側結束。
基於快排劃分的思路
上面的思路,是針對三個數的,如果有更多的數,怎麼處理呢?比如,4個,5個等等。下面根據快速的排序的啟發,介紹一種演算法,儘管在處理三個數的時候,比較次數會多些,但,具有很好的通用性。
思路來自快排的劃分部分,快排的劃分部分:給定pivot,然後將資料劃分為<=pivot和>pivot兩部分。這樣,三個數字時,需要兩次劃分:
第一次,用1作為pivot,劃分1到最左邊;
第二次,用2作為pivot,劃分2到左邊,則得到整體的排序。
最巧妙的思路
我們將1,2,3,替換為互質的2,3,5,得到如下:
2 | 1 | 1 | 3 | 3 | 2 |
3 | 2 | 2 | 5 | 5 | 3 |
之後,乘起來得到的900.這900裡,除以2,有多少個2,就有多少個1;然後除以3,有多少個3,就有多少個3對應的2;然後除以5,有多少個5,就有多少個5對應的3。這是如何保證的呢?因為2,3,5是互質的。
如下:
被除數 | 除數 | 商 | 餘數 | 排序結果 |
900 | 2 | 450 | 0 | 1 |
450 | 2 | 225 | 0 | 1 |
225 | 2 | 112 | 1 | 2嘗試結束,嘗試3 |
225 | 3 | 75 | 0 | 2 |
75 | 3 | 25 | 0 | 2 |
25 | 3 | 8 | 1 | 3嘗試結束,嘗試5 |
25 | 5 | 5 | 0 | 3 |
5 | 5 | 1 | 0 | 3 |
1 | 5 | 1 | 1 | 全部結束 |
最終結果為112233.上面的這種思路,實際上是計數的一種變種。沒有直接的技術,那自然就是可以的。
【分析完畢】
本文來自微信:待字閨中,2013-07-22釋出,原創@陳利人 ,歡迎大家繼續關注微信公眾賬號“待字閨中”。
相關文章
- 陣列的排序陣列排序
- 153. 尋找旋轉排序陣列中的最小值排序陣列
- 153. 尋找旋轉排序陣列中的最小值(中)排序陣列
- LeetCode-153-尋找旋轉排序陣列中的最小值LeetCode排序陣列
- 【LeetCode】153. 尋找旋轉排序陣列中的最小值LeetCode排序陣列
- 尋找陣列的中心索引陣列索引
- 陣列排序的實現陣列排序
- 1117陣列排序的技巧陣列排序
- 陣列排序陣列排序
- Javascript中的陣列物件排序JavaScript陣列物件排序
- 陣列的去重和排序陣列排序
- 陣列進行排序的方法陣列排序
- 陣列及陣列物件操作 ----------包括排序,去重,合併,翻轉等陣列物件排序
- 物件陣列排序物件陣列排序
- js陣列排序JS陣列排序
- JavaScript 陣列排序JavaScript陣列排序
- 第三章:查詢與排序(下)----------- 3.23 相關題解:排序陣列中找和的因子排序陣列
- iOS開發·必會的演算法操作:字串陣列排序+模型物件陣列排序iOS演算法字串陣列排序模型物件
- 尋找陣列中第K大的元素陣列
- 找一個陣列中特別的數陣列
- 1122. 陣列的相對排序(計數排序 / 自定義排序)陣列排序
- 為什麼處理排序陣列比未排序陣列快排序陣列
- 為什麼處理排序的陣列要比非排序的快排序陣列
- Leetcode[陣列] 26. 刪除排序陣列中的重複項LeetCode陣列排序
- LeetCode 關於陣列的相對排序LeetCode陣列排序
- 陣列物件的去重然後排序陣列物件排序
- 陣列氣泡排序陣列排序
- 陣列選擇排序陣列排序
- 二維陣列排序陣列排序
- c# 陣列排序C#陣列排序
- js陣列排序整理JS陣列排序
- 多維陣列排序陣列排序
- 陣列二:使用陣列可變函式為陣列排序陣列函式排序
- 尋找兩個有序陣列的中位數陣列
- javascript的boolean及陣列的indexJavaScriptBoolean陣列Index
- 記一次陣列操作:陣列 A 根據陣列 B 排序陣列排序
- 《Java從入門到失業》第三章:基礎語法及基本程式結構(3.9):陣列(陣列基本使用、陣列的迴圈、陣列拷貝、陣列排序、多維陣列)Java陣列排序
- 陣列排序函式-php陣列函式(一)陣列排序函式PHP
- 刪除排序陣列中的重複項排序陣列