Ugly Number II

Ugly number is a number that only have factors 2, 3 and 5.

Design an algorithm to find the nth ugly number. The first 10 ugly numbers are 1, 2, 3, 4, 5, 6, 8, 9, 10, 12...

If n=9, return 10.

这是<剑指offer>上的一题,非常经典.

这里丑数的定义是因数只有2,3,5的数,1也包括.直接的方法是从前往后扫,判断每个数是否为丑数.但是这种做法非常浪费时间,毕竟直接判断丑数的时间复杂度为O(n)级别的。

所以一个更优的方法是直接去构建丑数,下一个丑数总是从之前的丑数中乘2或者3、或者5产生的. 用M表示当前产生最大的一个丑数,我们用M2表示第一个乘以2就大于M的数,M3和M5类似。 M2,M3和M5可能存在相等,比如丑数为6时。所以从前往后扫,只要*2,*3,*5第一次大于已有的最后一个丑数,都有可能为下一个丑数,取其中的最小值.之后更新乘2,乘3,乘5的index。如果新生成的丑数只是2,3,5中一个的幂次,则更新这个数对应的数字的index。多个则更新多个,最多同时更新这三个数的index。

剑指offer原解是用while循环更新,但是实际每次2,3,5对应的index顶多更新一个或者不更新,if语句足够了,而且也要快很多。代码如下:

class Solution(object):
    def nthUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n <= 0:
            return 0
        uglyArray = [1]
        curIndex = 1
        p2index = p3index = p5index = 0
        while curIndex < n:
            minVal = min(uglyArray[p2index]*2,  uglyArray[p3index]*3, uglyArray[p5index]*5)
            if minVal == uglyArray[p2index]*2:
                p2index += 1 
            if minVal == uglyArray[p3index]*3:
                p3index += 1
            if minVal == uglyArray[p5index]*5:
                p5index += 1
                
            curIndex += 1
            uglyArray.append(minVal)
            
        return uglyArray[-1]
原文地址:https://www.cnblogs.com/sherylwang/p/5592021.html