题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
解题思路
同样的,我们首先想到的可能就是遍历判断,但是每个数都要计算一次是不是ugly,很是麻烦。于是我们想,能不能只对ugly进行计算呢,显然是可以的。
我们用一个数组来从小到大存放ugly,那现在的问题就是排序问题了,我们如何来保障这里面的数组是排好序的呢?
我们把当前数组里面最大的ugly记为M,那么,下一个ugly肯定是前面的数与2或者3或者5的乘积中的最小值。然后我们拿这个最小值和M进行比较,如果小于M,就说明已经存在于数组中,如果大于M,则说明需要添加进数组。需要注意的是,我们每次判断之后,我们只需要第一个比M大的值,其他的以后会重新计算。程序中通过t2、t3、t5分别记录上次计算用到的ugly的相应序号。
比如现在res中存放的是[1,2,3],此时,t2、t3都为1,t5为0,min(res[1] * 2, min(res[1] * 3, res[1] * 5)) 结果为4,res变为[1,2,3,4],判断后t2变成2,以此类推。
因为7之前的数(7除外)都是ugly,所以程序一开始的判断可以和i直接写index < 7。
python 代码实现:# -*- coding:utf-8 -*-
class Solution:
def GetUglyNumber_Solution(self, index):
# write code here
if index < 7:
return index;
res = [1]
t2 = t3 = t5 = 0
for i in range(1,index):
res.append(min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5)))
if res[i] == res[t2] * 2:
t2 += 1
if res[i] == res[t3] * 3:
t3 += 1
if res[i] == res[t5] * 5:
t5 += 1
return res[-1]