每日一道算法题-寻找丑数
?
題目:我們把只包含因子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整除,我們就連續(xù)除以2;能被3整除,我們就連續(xù)除以3;能被5整除,我們就連續(xù)除以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{M2,M3,M5}即可。
int?GetUglyNumber_Solution2(int?index)
{
????if(index <= 0)
????????return?0;
?
????int?*pUglyNumbers =?new?int[index];
????pUglyNumbers[0] = 1;
????int?nextUglyIndex = 1;
?
????int?*pMultiply2 = pUglyNumbers;
????int?*pMultiply3 = pUglyNumbers;
????int?*pMultiply5 = pUglyNumbers;
?
????while(nextUglyIndex < index)
????{
????????int?min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
????????pUglyNumbers[nextUglyIndex] = min;
?
????????while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
????????????++pMultiply2;
????????while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
????????????++pMultiply3;
????????while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
????????????++pMultiply5;
?
????????++nextUglyIndex;
????}
?
????int?ugly = pUglyNumbers[nextUglyIndex - 1];
????delete[] pUglyNumbers;
????return?ugly;
}
?
int?Min(int?number1,?int?number2,?int?number3)
{
????int?min = (number1 < number2) ? number1 : number2;
????min = (min < number3) ? min : number3;
?
????return?min;
}
第二種方法由于不需要在非丑數的整數花費時間,因而時間復雜度要小很多,在vc6+win7的平臺上,index=1500時,方法1的運行時間為40s,方法2的時間是1s;然而方法2需要動態(tài)分配內存,占用空間,而方法2則沒有這樣的內存開銷。說白了,第二種方法是用空間換時間
?
歡迎支持筆者新作:《深入理解Kafka:核心設計與實踐原理》和《RabbitMQ實戰(zhàn)指南》,同時歡迎關注筆者的微信公眾號:朱小廝的博客。總結
以上是生活随笔為你收集整理的每日一道算法题-寻找丑数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows使用opencv训练模型过
- 下一篇: Java线程面试题 Top 50