參考自:http://www.cnblogs.com/python27/archive/2011/11/24/2261550.html
題目:我們把只包含因子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,則該數是素數,否則是醜數。
代碼如下:
func isUglyNumber(number:Int)->Bool
{
var number1 = number
while number1 % 2 == 0
{
number1 /= 2
}
while number1 % 3 == 0
{
number1 /= 3
}
while number1 % 5 == 0
{
number1 /= 5
}
if number1 == 1
{
return true
}
else{
return false
}
}
func getUglyNumber1(index:Int)->Int{
if index <= 0{
return 0
}
var number:Int = 0
var count:Int = 0
while(count < index)
{
++number
if isUglyNumber(number){
++count
}
}
return number
}
上面計算中主要的不足在於,逐一遍歷,這樣對於不是醜數的數的判斷會造成大量的時間浪費,如果能夠根據已經計算好的醜數,計算出下一個醜數就可以避免這種情況,實現從醜數到醜數的高效算法,根據定義可知,後面的醜數肯定是前面已知醜數乘以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}即可
(相當於將之前得到的醜數放到一個數組array裏,然後分別將數組array裏的醜數乘以2,將其與數組array的最後一個醜數b相比,一旦大於b,就稱其爲上述中的M2,同理可得M3,M5)
代碼如下:
func getUglyNumber2(index:Int)->Int{
var uglyNum:Int = 1
if index <= 0{
return 0
}
var uglyArray:Array<Int> = [1]
var m2Array:Array<Int> = Array()
var m3Array:Array<Int> = Array()
var m5Array:Array<Int> = Array()
while uglyArray.count < index{
var m2:Int = 0
var m3:Int = 0
var m5:Int = 0
m2Array = uglyArray
m3Array = uglyArray
m5Array = uglyArray
for (index,value) in enumerate(m2Array){
m2Array[index] = value*2
if m2Array[index] > uglyArray.last{
m2 = m2Array[index]
break
}
}
for (index,value) in enumerate(m3Array){
m3Array[index] = value*3
if m3Array[index] > uglyArray.last{
m3 = m3Array[index]
break
}
}
for (index,value) in enumerate(m5Array){
m5Array[index] = value*5
if m5Array[index] > uglyArray.last{
m5 = m5Array[index]
break
}
}
uglyNum = min(m2, m3, m5)
uglyArray.append(uglyNum)
}
return uglyNum
}
在此感謝http://www.cnblogs.com/python27/的每日一算法的分享