題目描述:題目:我們把只包含因子2、
3和5的數稱作醜數(ugly number)
。例如6、8
都是醜數,但
14不是,因為它包含因子
7。習慣上我們把
1當做是第乙個醜數。求按從小到大的順序的第
1500
個醜數。
方法1: 最簡單的想法就是將所有的數枚舉,直到產生第n個醜數,但次方法比較耗時,且做了很多無用的工作。
方法2: 由醜數的性質可知,醜數的一定是另乙個醜數的2、3或5倍,又第乙個醜數為1,因此可以從1進行擴充套件尋找下乙個醜數
但是,怎樣保證尋找到的醜數是按照從大到小的順序呢?
最簡答的方法就是列舉,將前邊求得的所有醜數分別乘2、3、5,然後找到最小的比當前醜數大的那個數即為所求。但這樣時間複雜度較高,為o(n^2),有沒有更好的方法呢?
我們假設陣列中已
經有若干個醜數,排好
序後存在陣列中。我們把現有的最大醜數記做
m。現在我們來生成下乙個醜數,該醜數肯定是前面某乙個醜數乘以2、
3或者5的結果。我們首先考慮把已有的每個醜數乘以
2。在乘以
2的時候,能得到若干個結果小於或等於
m的。由於我們是按照順序生成的,小於或者等於
m肯定已經在陣列中了,我們不需再次考慮;我們還會得到若干個大於
m的結果,但我們只需要第乙個大於
m的結果,因為我們希望醜數是按從小到大順序生成的,其他更大的結果我們以後再說。我們把得到的第乙個乘以
2後大於
m的結果,記為
m2。同樣我們把已有的每乙個醜數乘以3和
5,能得到第乙個大於
m的結果m3和
m5。那麼下乙個醜數應
該是m2、m3
和m5三個數的最小者。
前面我們分析的時候,提到把已有的每個醜數分別都乘以2、
3和5,事實上是不需要的,因為已有的醜數是按順序存在陣列中的。對乘以
2而言,肯定存在某乙個醜數
t2,排在它之前的每乙個醜數乘以
2得到的結果都會小於已有最大的醜數,在它之後的每乙個醜數乘以
2得到的結果都會太大。我們只需要記下這個醜數的位置,同時每次生成新的醜數的時候,去更新這個
t2。對乘以3和
5而言,存在著同樣的t3和
t5。[cpp]view plain
copy
#include
using
namespace
std;
intmin(
inta,
intb,
intc)
intfinduglynum(
intn)
while
(pugly
//else if(ugly[pugly] == ugly[p3]*3)
//p2,p3,p5可能同時增加,
//如ugly[p2]=15, ugly[p3]=10, ugly[p5]=6時,
//下乙個產生的醜數相同,都為30,因此不能用else語句,應逐一判斷
if(ugly[pugly] == ugly[p3]*3)
if(ugly[pugly] == ugly[p5]*5)
pugly++;
} return
ugly[n-1];
} int
main()
} 參考:
google筆試題目
google筆試,據說小題都對就進入面試 1 兩個二進位制數的異或結果 2 遞迴函式最終會結束,那麼這個函式一定 不定項選擇 1.使用了區域性變數 2.有乙個分支不呼叫自身 3.使用了全域性變數或者使用了乙個或多個引數 3 以下函式的結果?int cal int x 4 以下程式的結果?void f...
面試題 醜數
我們把只包含因子2 3和5的數稱為醜數 ugly number 求按從大到小的順序的第1500個醜數。例如,6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當作第1個醜數。思路 先來乙個由定義得到的演算法,再看看有沒有優化空間。bool isugly int number while n...
一道google筆試題
題目 有四個執行緒1 2 3 4。執行緒1的功能就是輸出1,執行緒2的功能就是輸出2,以此類推.現在有四個檔案abcd。初始都為空。現要讓四個檔案呈如下格式 a 1 2 3 4 1 2.b 2 3 4 1 2 3.c 3 4 1 2 3 4.d 4 1 2 3 4 1.三種鎖策略耗時不同,第二種最快...