这个题解使用了最小堆来解决超级丑数问题。具体思路如下:
1. 初始化一个结果数组 ans,并将 1 作为第一个超级丑数加入 ans。
2. 使用一个最小堆 pq 存储 (prime, idx) 元组,其中 prime 表示质数,idx 表示该质数在 primes 数组中的下标。最小堆按照 prime 值进行排序。
3. 初始化一个数组 primes_idx,用于记录每个质数在 ans 数组中的下标。
4. 循环 n-1 次,每次从最小堆中取出最小的 (prime, idx) 元组,将 prime 加入 ans 数组。
5. 更新 primes_idx[idx],找到下一个未被使用的 ans[primes_idx[idx]],将其与当前质数相乘,得到新的超级丑数,并将其加入最小堆中。
6. 最终返回 ans 数组的最后一个元素,即第 n 个超级丑数。
时间复杂度: O(n * log k),其中 n 是要求的超级丑数的编号,k 是质数数组的长度。
空间复杂度: O(n + k),其中 n 是要求的超级丑数的编号,k 是质数数组的长度。
class Solution:
def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int:
ans = [1] # 结果数组,初始化为 [1]
ans_idx = [0] # 记录每个质数在 ans 数组中的下标
primes_idx = [0 for _ in range(len(primes))] # 记录每个质数在 ans 数组中的下标
pq = [(prime, idx) for idx, prime in enumerate(primes)] # 初始化最小堆
heapq.heapify(pq) # 建立最小堆
for _ in range(n-1):
cur, idx = heapq.heappop(pq) # 取出最小的超级丑数及其对应的质数下标
ans.append(cur) # 将当前超级丑数加入结果数组
ans_idx.append(idx) # 记录当前超级丑数对应的质数下标
primes_idx[idx] += 1 # 更新对应质数的下标
while ans_idx[primes_idx[idx]] > idx: # 找到下一个未被使用的 ans[primes_idx[idx]]
primes_idx[idx] += 1
heapq.heappush(pq, (primes[idx] * ans[primes_idx[idx]], idx)) # 将新的超级丑数加入最小堆
return ans[-1] # 返回第 n 个超级丑数