题目描述:
设计一个算法,找出只含素因子2
,3
,5
的第 n 小的数。
符合条件的数如:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...
我们可以认为1
也是一个丑数
如果n = 9
, 返回 10
要求时间复杂度为O(nlogn)或者O(n)
代码实现:
class Solution:
"""
@param n: An integer
@return: the nth prime number as description.
"""
def nthUglyNumber(self, n):
# write your code here
'''
num=0 #记录第几个只含素因子的数
i=0 #记录第几个数
j=1 #从1开始
ans=0
while num<n:
ans = j
while j / 2==1:
j = j/2
if j==1:
num+=1
j=1+ans
continue
while j / 3 ==1:
j = j/3
if j==1:
num+=1
j=ans+1
continue
while j / 5 ==1:
j = j/5
if j==1:
num+=1
j=ans+1
continue
j=ans+1
return ans
#不知名得错误
'''
'''
i=1
num=1
while num<n:
a=isUgly(i)
i+=1
if a:
num +=1
return i
def isUgly(num):
if num < 1:
return None
if num==1:
return True
while num%2==0:
num=num/2
while num%3==0:
num=num/3
while num%5==0:
num=num/5
if num==1:
return True
return False
#运行超时
'''
#用堆heap,参考https://www.jiuzhang.com/solution/ugly-number-ii/#tag-highlight-lang-python
import heapq
heap = [1]
visited = set([1])
val = None
for i in range(n):
val = heapq.heappop(heap)
for multi in [2,3,5]:
if val*multi not in visited:
visited.add(val*multi)
heapq.heappush(heap,val*multi)
return val
思路:
用堆来存储丑数,初始堆中只有一个1个丑数1,然后循环n次,每次从堆中取出一个丑数(堆顶上的值),用这个值分别乘以2,3,5,并将结果压到堆中,直到遍历到第n次,从堆中弹出的堆顶的值就是第n个丑数。同时将一个集合作为中间件,比较好判断乘的结果存不存在堆中。
注:堆又被称为优先队列,但队列中出队列是按照进队列的先后顺序取出元素,而堆是元素的优先级取出元素。堆的主要操作是插入和删除最小元素(元素值本身为优先级键值,小元素享有高优先级)。