leetcode 313. 超级丑数
python版本 改进网络版
编写一段程序来查找第 n
个超级丑数。
超级丑数是指其所有质因数都是长度为 k
的质数列表 primes
中的正整数。
示例:
输入: n = 12,primes
=[2,7,13,19]
输出: 32 解释: 给定长度为 4 的质数列表 primes = [2,7,13,19],前 12 个超级丑数序列为:[1,2,4,7,8,13,14,16,19,26,28,32] 。
说明:
1
是任何给定primes
的超级丑数。- 给定
primes
中的数字以升序排列。 - 0 <
k
≤ 100, 0 <n
≤ 106, 0 <primes[i]
< 1000 。 - 第
n
个超级丑数确保在 32 位有符整数范围内
手动构造超级丑数的列表的时候,可以发现一个规律,每一个新的超级丑数,都是在primes列表里,按照某种乘法方式得到的比现有超级丑数大的最小数(因为升序排序)。因此难点在于如何确定这个“某种乘法”。
先解决了Ugly Number II题后,发现了有这么一个“某种乘法”:
每个新的丑数,都是primes乘上某一个已有的丑数。而且,某个primes乘上了一个已有的丑数以后,再也不会乘到比该丑数小的(也就是排在前面)的丑数,因为会乘出比它小的丑数,不可能再排到那之后。
因此,用一个数组t来记录每一个primes系数乘到了第几个丑数(都是从1开始),每次寻找下一个丑数的时候,遍历该数组,找到乘出来最小的那个新丑数,存到超级丑数数组里。同时,如果这个新的超级丑数是某个prime和它t数组里对应的丑数的乘法结果,那么把该prime在t数组里的下标加一。
但是。。。我发现一个问题 python这样写会超时
所以我改进了下 大概就是减少判断最小值的计算次数 用一个数组去存储值 变动后更新 python AC
class Solution: def nthSuperUglyNumber(self, n, primes): """ :type n: int :type primes: List[int] :rtype: int """ data = {} res = [1] for i in primes: data[i] = 0 arr = [] for i in range(2, n + 1): if not arr: for j in primes: now=j * res[data[j]] arr.append(now) mins =min(arr) res.append(mins) for k in range(0,len(primes)): v=primes[k] if arr[k]==mins: data[v] += 1 arr[k]=v * res[data[v]] return res.pop()