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()

 

posted @ 2018-09-06 03:49  cnlh  阅读(885)  评论(0编辑  收藏  举报