思路
设计一个算法,找出只含素因子2,3,5 的第 n 小的数。
符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
注意事项
我们可以认为1也是一个丑数
样例
如果n = 9, 返回 10
分析
1是最小丑数
需要找到第n小的丑数,他的因子只含有2、3、5(可以重复)
每下一个数字可能是前面序列的数字的2,3,5倍, 那我们从1开始
f[1] = 1
f[2] = min(f[1] * 2, f[1] * 3, f[1] * 5) = f[1] * 2 = 2
f[3] = min(f[1] * 3, f[2] * 2) = f[1] * 3
f[4] = min(f[1] * 5, f[2] * 2, f[3] * 2) = f[2] * 2 = 4
f[5] = min(f[1] * 5, f[2] * 3, f[3] * 2) = f[1] * 5 = 5
f[6] = min(f[2] * 3, f[3] * 2) = f[2] * 3 = 6
f[7] = min(f[2] * 5, f[3] * 3, f[4] * 2) = f[4] * 2 = 8
我们可以看到
i2 代表还可以乘2的下标
i3 代表还可以乘3的下标
i5 代表还可以乘5的下标
f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
#####################
重新模拟一边 f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
i2, i3, i5 =1, 1, 1 f[1] = 1
i2, i3, i5 =1, 1, 1 f[2] = min(f[1] * 2, f[1] * 3, f[1] * 5) = min(2, 3, 5) = 2 i2 = 2
i2, i3, i5 =2, 1, 1 f[3] = min(f[2] * 2, f[1] * 3, f[1] * 5) = min(4, 3, 5) = 3 i3 = 2
i2, i3, i5 =2, 2, 1 f[4] = min(f[2] * 2, f[2] * 3, f[1] * 5) = min(4, 6, 5) = 4 i2 = 3
i2, i3, i5 =3, 2, 1 f[5] = min(f[3] * 2, f[2] * 3, f[1] * 5) = min(6, 6, 5) = 5 i5 = 2
i2, i3, i5 =3, 2, 2 f[6] = min(f[3] * 2, f[2] * 3, f[2] * 5) = min(6, 6, 10) = 6 i2, i3 = 4, 3
i2, i3, i5 =4, 3, 2 f[7] = min(f[4] * 2, f[3] * 3, f[2] * 5) = min(8, 9, 10) = 8 i2 = 5
i2, i3, i5 =5, 3, 2 f[7] = min(f[5] * 2, f[3] * 3, f[2] * 5) = min(10, 9, 10) = 9 i3 = 4
···········
于是我们得到结论
f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
Python
class Solution:
"""
@param n: An integer
@return: the nth prime number as description.
"""
def nthUglyNumber(self, n):
# write your code here
i2, i3, i5 = 1, 1, 1
f = [0 for x in range(n + 1)]
f[1] = 1
if n < 1:
return -1
for i in range(2, n + 1):
f[i] = min(f[i2] * 2, f[i3] * 3, f[i5] * 5)
if f[i] == f[i2] * 2:
i2 += 1
if f[i] == f[i3] * 3:
i3 += 1
if f[i] == f[i5] * 5:
i5 += 1
return f[n]
if __name__ == "__main__":
s = Solution()
a = 9
print(s.nthUglyNumber(a))
Go
package main
import (
"fmt"
)
/**
* @param n: An integer
* @return: the nth prime number as description.
*/
func nthUglyNumber(n int) int {
// write your code here
var i2, i3, i5 int
var f []int
i2, i3, i5 = 1, 1, 1
f = make([]int, n+1)
f[1] = 1
for i := 2; i <= n; i++ {
f[i] = min(min(f[i2]*2, f[i3]*3), f[i5]*5)
if f[i] == f[i2]*2 {
i2++
}
if f[i] == f[i3]*3 {
i3++
}
if f[i] == f[i5]*5 {
i5++
}
}
return f[n]
}
func min(x int, y int) int {
if x <= y {
return x
}
return y
}
func main() {
fmt.Println(nthUglyNumber(9))
}