1. 程式人生 > >《劍指offer》---醜數

《劍指offer》---醜數

每次 source off In end 個數 算法 程序 range

本文算法使用python3實現


1. 問題1

1.1 題目描述:

??把只包含因子2、3和5的數稱作醜數(Ugly Number)。判斷一個數是否是醜數。
??時間限制:1s;空間限制:32768K


1.2 思路描述:

??大致思路:將該數依次除以 $ 2,3,5 $ ,若最後商為 $ 1 $ 則是醜數,否則,不是醜數。


1.3 程序代碼:

class Solution:
    def isUgly(self, num):
        '''判斷num是否是醜數'''
        if num <= 0:
            return
False for i in [2,3,5]: while num % i == 0: num = num / i if num == 1: return True else: return False




2. 問題2

2.1 題目描述:

??把只包含因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因為它包含因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。
??時間限制:1s;空間限制:32768K


2.2 思路描述:

??大致思路
??(1)設置數組 $ UglyNum=[] $ 用來保存醜數。並將 $ 1 $ 添加進數組 $ UglyNum=[1] $。基數設置為 $ 2,3,5 $ 。以基數為質因子的醜數的下標為 $ id2,idx3,idx5 $ ,起始均為 $ 0 $ 。
??(2)計算: $ 2 \times UglyNum[idx2] = 2 \times 1 , 3 \times UglyNum[idx3] = 3 \times 1, 5 \times UglyNum[idx5] = 5 \times 1 $ ,將最小的數存入數組 $ UglyNum =[1,2] $ ,以 $ 2 $ 為基數的醜數下標增加 $ 1 $ : $ idx2 = 0+1 = 1 $ ,其余不變。

??(3)計算: $ 2 \times UglyNum[idx2] = 2 \times 1 , 3 \times UglyNum[idx3] = 3 \times 1 , 5 \times UglyNum[idx5] = 5 \times 1 $ ,將最小的數存入數組 $ UglyNum =[1,2,3] $ ,以 $ 3 $ 為基數的醜數下標增加 $ 1 $ : $ idx3 = 0+1 = 1 $ ,其余不變。
??(4)計算: $ 2 \times UglyNum[idx2] = 2 \times 2 , 3 \times UglyNum[idx3] = 3 \times 2 , 5 \times UglyNum[idx5] = 5 \times 1 $ , 將最小的數存入數組 $ UglyNum =[1,2,3,4] $ ,以 $ 2 $ 為基數的醜數下標增加 $ 1 $ : $ idx2 = 1+1 = 2 $ ,其余不變。
??(5)計算: $ 2 \times UglyNum[idx2] = 2 \times 3 , 3 \times UglyNum[idx3] = 3 \times 2 , 5 \times UglyNum[idx5] = 5 \times 1 $ , 將最小的數存入數組 $ UglyNum =[1,2,3,4,5] $ ,以 $ 5 $ 為基數的醜數下標增加 $ 1 $ : $ idx5 = 0+1 = 1 $ ,其余不變。
??(6)以此類推,計算 $ n-1 $ 次,並將值存入數組中。返回數組最後一個值即為所求。


2.3 程序代碼:

class Solution:
    def GetUglyNumber_Solution(self, index):
        '''返回第index個醜數'''
        if index == 0:
            return 0
        # 保存前N個醜數
        uglyNum = [1]
        # 起始下標都為0
        idx2, idx3, idx5 = 0, 0, 0
        # 再存index-1個數即可
        for i in range(index-1):
            n2, n3, n5 = uglyNum[idx2]*2, uglyNum[idx3]*3, uglyNum[idx5]*5
            Min = min(n2, n3, n5)
            uglyNum.append(Min)
            idx2 += (Min == n2)
            idx3 += (Min == n3)
            idx5 += (Min == n5)
        return uglyNum[-1]




3. 問題3

3.1 題目描述:

??有一個列表 $ primes $ ,把只包含因子為列表 $ primes $ 中元素的數稱作超級醜數( Super Ugly Number)。例如 當列表為 $ primes = [2,3,5] $ 時,即為問題2。


3.2 思路描述:

??思路同問題二一致。


3.3 程序代碼:

class Solution:
    def nthSuperUglyNumber(self, index, primes):
        '''超級醜數
        Args:
            index: n
            primes: 列表
        當某個數的因子只有primes中的元素時,作為超級醜數,求出第n個超級醜數
        '''
        if index == 0 or not primes:
            return 0
        if index == 1:
            return 1
        uglyNum = [1]
        lens = len(primes)
        # idx為列表,保存每次基數下標
        idx = [0] * lens
        # num保存每次乘積值
        num = [0] * lens
        for i in range(index-1):
            # 更新每次乘積值
            for k in range(lens):
                num[k] = uglyNum[idx[k]] * primes[k]
            Min = min(num)
            uglyNum.append(Min)
            # 更新基數下標值
            for k in range(lens):
                idx[k] += (Min == num[k])
        return uglyNum[-1]

《劍指offer》---醜數