Day81 超級丑數

直接抄星主的:

編寫一段程序來查找第 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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。