小程式員的趣味題(一)
1.在排序數組中,找出某整數出現的次數
問題定義:給定一個整數數組arr,數組中元素的個數是n,數組arr已經排好序,要在arr中找到某個某個整數x出現的次數,比如arr[] = {1,2,2,3,5,10},找到2的出現次數就是2。
問題分析:相必看到有序數組的字樣,想到利用二分應該是很順利成章的事了。我們可以利用二分搜尋求出x在arr中出現的第一個位置lo和最後一個位置hi,然後計算hi-lo+1的值就是x在arr出現的次數了,當然也有可能x並沒有在arr中出現過,這時hi和lo都等於-1。時間複雜度是兩個二分的複雜度:2*O(log n)。看看代碼是怎麼實現的吧。。
相關代碼: View Code
小結:有人也提到了這樣解法,即:先利用二分找到x在arr中出現的第一個位置lo,然後從lo下一位置開始向後直到下標達到n-1或者找到不等於x的情況結束,每前進一步,x出現的次數加 1,這樣也能求出x在arr中出現的次數,但是不要忘了這種情況,即arr = {1,1,1,1,1,1},然後x = 1,那麼這時利用這種方法的時間複雜度就是O(n+log n) 了。也就是說在最壞的情況下,時間複雜度太高。
2.去掉字串中多餘的空格
問題描述:給定一個字串數組,要求去掉首部和尾部的所有空格,字串中間的空格出現1次以上只保留一個空格,比如str[] = “ Wo shi Vincent ”,經過處理後應為“Wo shi Vincent”。
問題分析:這是一個簡單的字串處理的問題,顯然開頭、結尾、和中間的空格處理方式是不一樣的,我的思路是遍曆一遍字元數組,首先處理開頭的空格,方法是:全部刪除;然後是字串中間的空格,方法是:遇到空格,值保留第一個空格;遍曆結束後,新串的最後一個字元是空格,就代表是原字串尾部有空格存在,所以要去掉。如此一來就完事了,值需要遍曆一遍,時間複雜度是O(n)。
相關代碼: View Code
3.求1024。的結果中末尾有多少個0
問題分析:首先1024。呀,是多麼大的一個數呢。。想求出來結果然後在看末尾有多少0是不現實的,我們可以分析要求的是:末尾有多少個0。那麼的0的個數有什麼決定的呢。10 = 2 * 5 ,顯然一對(2 , 5)就能湊出一個末尾0,也就是說末尾0的個數是由因子2和5的個數決定的,更確切的說是由因子的個數決定的(考慮一下為什麼吧。。),那麼1~1024這1024個數中包含多少個因子5呢。顯然這1024個數有的包含1個因子5,有的包含兩個因子5(5^2 = 25),有得包含三個因子5(5^3 = 125),有的包含4的因子5(5^4 = 625)。那麼一共包含多少因子5呢。
包含一個因子5的數有 1024 / 5 = 204 個。
包含兩個因子5的數有 1024 / 25 = 40 個。
包含三個因子5的數有 1024 / 125 = 8 個。
包含四個因子5的數有 1024 / 625 = 1 個。
也就是說1~1024這1024個數一共包含因子5的個數是: sum = 204 + 40 + 8 + 1 個。
小結:注意類似的問題可以借鑒這個題的解題思路~~~~~~
4.給定能隨機產生整數1到5的函數,寫出能隨機產生整數1到7的函數
問題分析:現在給了一個能隨機產生1~5的隨機函數,怎樣利用這個已知條件產生一個1~7的隨機函數呢。既然要產生的是隨機數那麼產生1,2,3,4,5,6,7的機率就應該是一樣的。顯然現在光產生1~5之間的數就不夠了,我們想到應該要加大產生數的範圍,並且加大範圍的同時還要保證每個數產生的機率一樣,於是有這樣一種方法用這個運算式來擴大產生數範圍:rand5()*5+rand5(),新的資料範圍變成:6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30.並且可以看出來這個25個數出現的可能性是一樣的,於是我們可以只用6~26之間的21個數變成1~7這7個數,於是就是要每3個數對應一個數,即:
6,7,8對應1
9,10,11對應2
…………
24,25,26對應7
這種變化對應的方式是(6 - 3)/ 3 = 1,(7 - 3) / 3 = 1,(8-3) / 3 = 1.看看代碼吧:
相關代碼: View Code