丑数集合(263、264、313)

题目说明:1是丑数 

暴力解法:

num反复除2,3,5直到不能整除。最终判断剩余的数字是否为1,如果是1则为丑数,否则不是丑数。

类似求质数的解法:link

每一个丑数必然是之前丑数与2,3或5的乘积得到的,这样下一个丑数就是用之前的丑数分别乘以2,3,5。

详细算法步骤: 
(1)从第一个丑数1开始,求出1*2=2 ,1*3=3 ,1*5 = 5。 
(2)取上面乘积中大于1的最小值2( 即 min(2,3,5)),作为第二个丑数(丑数是个递增序列。所以第i+1个丑数一定比第i个丑数大) 
(3)求丑数2之前的丑数与2、3、5的乘积:1*2=2 ,1*3=3 ,1*5 = 5; 2*2 = 4; 2*3 = 6。 2*5 =10。 
(4)取上面乘积中大于2的最小值3,作为第三个丑数

(i)取出丑数i之前的丑数分别与2、3、5的乘积

(i+1)取乘积中大于i的最小值作为丑数

(i+2)反复(i)(i+1)的步骤直到计数器等于N

def isUgly(self, num):
    """
    :type num: int
    :rtype: bool
    """
    # 暴力
    while num>1:
        if num%2==0:
            num = num//2
        elif num%3==0:
            num = num//3
        elif num%5==0:
            num = num//5
        else:
            break
    if num==1:
        return True
    else:
        return False

(*^▽^*) 简化

def isUgly(self, num):
    """
    :type num: int
    :rtype: bool
    """
    if num <= 0:
        return False
    for x in [2, 3, 5]:
        while num % x == 0:
            num = num / x
    return num == 1

# 找出第 n 个丑数
class Solution:
    def nthUglyNumber(self, n):
        """
        :type n: int
        :rtype: int
        """
        if n <= 0:
            return False
        t1 = 0
        t2 = 0
        t3 = 0
        res = [1]
        while len(res) < n:
            # 长度可以代表第几个
            res.append(min(res[t1]*2, res[t2]*3, res[t3]*5))
            print(res)
            if res[-1] == res[t1]*2:
                t1 += 1 # t1代表2所产生的丑数到第几步了
            if res[-1] == res[t2]*3:
                t2 += 1
            if res[-1] == res[t3]*5:
                t3 += 1
        return res[-1]

# 和264的区别在于,264是给定primes的个数,求第n个丑数
# 本题事先不知道primes的个数,所以t1,t2,...tn无法确定。

class Solution:
    def nthSuperUglyNumber(self, n, primes):
        """
        :type n: int
        :type primes: List[int]
        :rtype: int
        """
        dp = [1] # res=[]

        lenPrimes = len(primes)
        idxPrimes = [0] * lenPrimes # 类似于t1,t2,t3记录位置
        # print(idxPrimes) # [0, 0, 0, 0]
        counter = 1
        while counter < n:
            min = pow(2, 32)
            for i in range(0, lenPrimes):
                # 找出最小值
                temp = dp[idxPrimes[i]] * primes[i]
                # 求最小的值
                if temp < min:
                    min = temp

            for i in range(0, lenPrimes):
                # 更新最小值所在的位置,类似t1+=1
                # === if res[-1] == res[t1]*2:
                if min == dp[idxPrimes[i]] * primes[i]:
                    idxPrimes[i] += 1
            print(idxPrimes)
            # res.append(min(res[t1]*2, res[t2]*3, res[t3]*5))
            dp.append(min)
            counter += 1
        # print(counter-1) # 11
        # print(len(dp))# 12
        return dp[counter - 1]

 

回去看视频啦!~! (~ ̄▽ ̄)~ 

猜你喜欢

转载自blog.csdn.net/weixin_31866177/article/details/84403687