题目说明: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]
回去看视频啦!~! (~ ̄▽ ̄)~
学了dp再来重新看这个问题。。。
首先给定一个解题基本思路:
假设为丑数,
则可以认为
皆为丑数。
并且下一丑数最小值一定为