Ugly Number II
题目描述
Write a program to find the n-th ugly number.
Ugly numbers are positive numbers whose prime factors only include 2, 3, 5
. For example, 1, 2, 3, 4, 5, 6, 8, 9, 10, 12
is the sequence of the first 10
ugly numbers.
Note that 1
is typically treated as an ugly number.
解题方法
丑陋数序列可以拆分为下面3个子列表:
(1) 1×2, 2×2, 3×2, 4×2, 5×2, …
(2) 1×3, 2×3, 3×3, 4×3, 5×3, …
(3) 1×5, 2×5, 3×5, 4×5, 5×5, …
我们可以发现每一个子列表都是丑陋数本身(1, 2, 3, 4, 5, …) 乘以 2, 3, 5
接下来我们使用与归并排序相似的合并方法,从3个子列表中获取丑陋数。每一步我们从中选出最小的一个,然后向后移动一步。
三个指针p2,p3,p5分别代表下一次乘以2,3,5的来比较ugly number的index,如果用过了就指向下一个ugly number
Solution
一开始错误的作法!
class Solution(object):
def nthUglyNumber(self, n):
"""
:type n: int
:rtype: int
"""
if n < 0:
return -1
if n == 1:
return 1
p = 1
result = [1]
p2, p3, p5 = 0, 0, 0
while p < n:
m2 = result[p2] * 2
m3 = result[p3] * 3
m5 = result[p5] * 5
m = min(m2, m3, m5)
result.append(m)
if m == m2:
p2 += 1
elif m == m3:
p3 += 1
elif m == m5:
p5 += 1
p += 1
return result[-1]
这种做法是错误的,因为m2,m3,m5可能会有相同的,会导致重复的数重复加到数组内,其实应该跳过 比如n等于7时
2 3 5 n = 2
2
4 3 5 n =3
3
4 6 5 n = 4
4
6 6 5 n = 5
5
6 6 10 n = 6
6
8 6 10 n = 7
6
可以看到当m2,m3的指向的数分别乘以2,3时,得到的都是6,6只能加到数组中一次,所以应该对它们都跳过!!
正确的作法
class Solution(object):
def nthUglyNumber(self, n):
"""
:type n: int
:rtype: int
"""
if n < 0:
return -1
if n == 1:
return 1
p = 1
result = [1]
p2, p3, p5 = 0, 0, 0
while p < n:
m2 = result[p2] * 2
m3 = result[p3] * 3
m5 = result[p5] * 5
m = min(m2, m3, m5)
result.append(m)
if m == m2:
p2 += 1
if m == m3:
p3 += 1
if m == m5:
p5 += 1
p += 1
return result[-1]