0.题目
1. 动态规划 / 三指针 o(n) o(n)
丑数中,第n个丑数 是由 前面n-1个丑数 ✖️2/✖️3/✖️5 得到的。
所以用p2、p3、p5 三个指针记录 还没✖️2、✖️3、✖️5的位置。
dp[p2]*2、 dp[p3]*3、dp[p5]*5 中最小的放在dp中。
class Solution(object):
def nthUglyNumber(self, n):
dp = [0]*(n+1) #0+记录n个丑数
dp[1]=1
p2=p3=p5=1
for i in range(2,n+1):
num2,num3,num5=dp[p2]*2,dp[p3]*3,dp[p5]*5 #p2,p3,p5指未遍历过的数
dp[i]=min(num2,num3,num5)
print(num2,num3,num5,p2,p3,p5,i)
if dp[i]==num2:
p2+=1 #下标
if dp[i]==num3:
p3+=1 #下标
if dp[i]==num5:
p5+=1 #下标
return dp[n]
2. 最小堆 o(nlogn) o(n)
class Solution:
## 最小堆
def nthUglyNumber(self, n):
factors = [2,3,5]
seen = {1}
heap = [1]
for i in range(n-1):
cur = heapq.heappop(heap) #1 出堆
for factor in factors:
if (nxt := cur*factor) not in seen:
seen.add(nxt) #1 2 3 5
heapq.heappush(heap,nxt) #小根堆【1】 2 3 5
return heapq.heappop(heap)