每日一道演算法題 尋找醜數

2021-06-21 22:05:14 字數 1212 閱讀 4039

題目:我們把只包含因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第1500個醜數。

分析:尋找乙個數是不是滿足某種數(質數,水仙數)等,最簡單的方法就是遍歷,對於任意乙個醜數必定可以寫成2^m*3^n*5^p,因而對於乙個醜數,只含有2,3,5因子,也就意味著該數number%2==0;number%3==0;number%5==0,如果乙個數能被2整除,我們就連續除以2;能被3整除,我們就連續除以3;能被5整除,我們就連續除以5;如果最後得到1,則該數是素數,否則是醜數。

上面計算中主要的不足在於,逐一遍歷,這樣對於不是醜數的數的判斷會造成大量的時間浪費,如果能夠根據已經計算好的醜數,計算出下乙個醜數就可以避免這種情況,實現從醜數到醜數的高效演算法,根據定義可知,後面的醜數肯定是前面已知醜數乘以2,3,5得到的。

我們假設乙個陣列中已經有若干醜數,並且這些醜數是按順序排列的,我們把現有的最大醜數記為max,則下乙個醜數肯定是前面醜數乘以2,3,5得到的。不妨考慮乘以2得到的情況,我們把陣列中的每乙個數都乘以2,由於原陣列是有序的,因為乘以2後也是有序遞增的,這樣必然存在乙個數m2,它前面的每乙個數都是小於等於max,而包括m2在內的後面的數都是大於max的,因為我們還是要保持遞增順序,所以我們取第乙個大於max的數m2。同理對於乘以3的情況,可以取第乙個大於max的數m3,對於乘以5的情況,可以取第乙個大於max的數m5。

最終下乙個醜數取:min即可。

int getuglynumber_solution2(int index)

int ugly = puglynumbers[nextuglyindex - 1];

delete puglynumbers;

return ugly;

}int min(int number1, int number2, int number3)

第二種方法由於不需要在非醜數的整數花費時間,因而時間複雜度要小很多,在vc6+win7的平台上,index=1500時,方法1的執行時間為40s,方法2的時間是1s;然而方法2需要動態分配記憶體,占用空間,而方法2則沒有這樣的記憶體開銷。說白了,第二種方法是用空間換時間

每日一道演算法題 尋找醜數

題目 把只包含質因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做第乙個醜數。求按從小到大的順序的第1500個醜數。解題思路 第一種方法,暴力解法,從數字1開始遍歷,一直找到第1500個醜數為止,這種窮舉的思路是最簡單的,效率也是...

每天一道演算法題19 尋找醜數

原文 題目 我們把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8 都是醜數,但 14不是,因為它包含因子 7。習慣上我們把 1當做是第乙個醜數。求按從小到大的順序的第 1500 個醜數。分析 這是一道在網路上廣為流傳的面試題,據說google曾經採用過這道題。所謂乙個數m是另乙...

每天一道演算法題 醜數

題目描述 把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 使用兩個佇列乙個存放節點,乙個存放值。先將根節點加入到佇列中,然後遍歷佇列中的元素,遍歷過程中,訪問該元素的左...