美文网首页
Day81 超级丑数

Day81 超级丑数

作者: 快乐的老周 | 来源:发表于2020-09-27 14:21 被阅读0次

    直接抄星主的:

    编写一段程序来查找第 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 位有符整数范围内。
    
        # 来源:力扣(LeetCode)
        # 链接:https://leetcode-cn.com/problems/super-ugly-number
        # 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
    

    超级丑数题目来源:

    https://leetcode-cn.com/problems/super-ugly-number/

    首先理解题目,我做此题,读题好几遍,才完全明白超级丑数的定义。给定一个质数列表primes,如果一个数的所有质数列表是primes的子集,则这个数为超级丑数。

    题目要求,在给定primes情况下,求出第n个丑数。

    分析过程

    先从暴力枚举开始分析,假定primes等于[2,5,13],依次列举出所有肯能的丑数:1, 2, 4, 8,

    16, 32, ….

    糟糕!因为光使用一个素数2,就能列举出很多。幸好此题限定一个丑数的上限,在32

    位有符整数范围内(最大值为:2的31次方减1),即便如此穷举的情况还是很多。

    此题不太容易确定所有的丑数序列,完整的序列无法确定,排序也就无从谈起,因此通过从小到大排序后找出第n个丑数的方法就不可行。

    对于无法提前预知整个列表,或者构建出整个序列耗费时间或占用内存过大时,可以考虑使用堆,对应Python中的

    heapq 模块。

    这道题使用heapq的求解思路如下:

    1) 构建heapq,装入第一个元素,即素数1;

    2

    移出heapq的根元素ugly,遍历primes拿出prime,同时与prime的元素相乘,得到一个新的丑数,并装入到heapq中。备注:Python中heapq是一个小根堆,也叫做优先级队列,在装入heapq中时,对象内部总会维护一个小根堆,所以每次pop时,都是当前heapq的最小值。

    3

    利用上述特性,当移出n个元素时,实际上相当于从已排序好的列表中找到其第n个小的元素,这不就是丑数列表排序好后,第n个丑数吗!真是返回的结果。

    需要注意,丑数装入heapq时,不要出现重复。解决起来也很方便,使用集合set防止重复添加。

    class Solution:
        def nthSuperUglyNumber(self, n, primes):
            import heapq
            nums,ugly = [],0
            s = set()
            heapq.heapify(nums)
            heapq.heappush(nums,1)
            for _ in range(n):
                ugly = heapq.heappop(nums)
                for i in primes:
                    temp = ugly * i
                    if temp not in s:
                        s.add(temp)
                        heapq.heappush(nums,temp)
                        print(nums)
            return ugly
    
    
    def test_nthSuperUglyNumber():
        s = Solution()
        assert s.nthSuperUglyNumber(12, [2,7,13,19]) == 32
    
    

    相关文章

      网友评论

          本文标题:Day81 超级丑数

          本文链接:https://www.haomeiwen.com/subject/gegcuktx.html