劍指offer 醜數

2021-10-06 07:48:17 字數 2553 閱讀 3805

把只包含質因子2、3和5的數稱作醜數(ugly number)。例如6、8都是醜數,但14不是,因為它包含質因子7。 習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。

問題分析:醜數一定是有限個2、3、5的乘積因為所有的正整數都能分解成1與乙個或多個素數的乘積。如果乙個數是醜數,那麼反覆除以2、3、5後,一定會是1;如果乙個數不是醜數,那麼反覆除以2、3、5後,一定還會剩下了乙個質數無法被2、3、5整除。

程式設計內容:

1、判斷乙個整數是否是醜數?

2、給定區間,輸出醜數的個數或醜數。

3、求第n個醜數

尋找醜數演算法1:

(1)設定乙個計數器用來統計出現的醜數的個數

(2)從1開始遍歷每乙個整數,判斷是否是醜數,如果是醜數則計數器加1,否則遍歷下乙個整數。

(3)當計數器的值=n時,停止遍歷,輸出醜數。

尋找醜數演算法2:

從上乙個醜數推斷出下乙個醜數,而不需要從1開始遍歷再判斷。從1開始的10個醜數分別為1,2,3,4,5,6,8,9,10,12。可以發現除了1以外,醜數都是由某個醜數*2或者*3或者*5得到的。如2是醜數1*2得到的,3是醜數1*3得到的,4是醜數1*4得到的,5是醜數1*5得到的,6是醜數2*3得到的……

具體演算法步驟:

(1)從第乙個醜數1開始,求出1*2=2 ,1*3=3 ,1*5 = 5;

(2)取上面乘積中大於1的最小值2,作為第二個醜數(醜數是個遞增序列,所以第i+1個醜數一定比第i個醜數大)

(3)求醜數2之前的醜數與2、3、5的乘積:1*2=2 ,1*3=3 ,1*5 = 5; 2*2 = 4; 2*3 = 6; 2*5 =10;

(4)取上面乘積中大於2的最小值3,作為第三個醜數

(i)取出醜數i之前的醜數分別與2、3、5的乘積

(i+1)取乘積中大於i的最小值作為醜數

(i+2)重複(i)(i+1)的步驟直到計數器等於n

問題一:判斷乙個數是否為醜數

python**:

# -*- coding: utf-8 -*-

import sys

# 判斷乙個數是否為醜數

def isuglynumber(num):

if num<=0:

return false

elif num>=1:

for i in [2,3,5]:

while num%i==0:

num = num / i

if num == 1:

return true

else:

return false

if __name__ == '__main__':

try:

while true:

arr = int(input())

print(isuglynumber(arr))

except:

pass

def isuglynum(self, num):

while num % 2 == 0:

num /= 2

while num % 3 == 0:

num /= 3

while num % 5 == 0:

num /= 5

if num == 1:

return 1

return 0

這裡主要記錄乙個判斷乙個數是否為醜數的函式,基於此函式可以實現在乙個區間內輸出所有醜數,輸出第n個醜數。但是在劍指offer上,用這種思路來輸出第n個醜數因為執行時間太長不通過,這裡給出通過版的**

改進演算法:

劍指offer 醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 參考程式設計師面試金典 偽 如下 1 初始化array和佇列 q2 q3 q5 2 將1插入array 3 分別將1 2...

劍指Offer 醜數

我們把只包含因子 2 3 和 5 的數稱作醜數 ugly number 求按從小 到大的順序的第 1500 個醜數。例如 6 8都是醜數,但 14 不是,它包含因子 7。習慣上我們把 1當做第乙個醜數。解法一 逐一判斷是否是醜數,簡單但是不夠高效 數字n是數字m的因子說明m n 0。醜數的因子只有2...

劍指offer 醜數

把只包含因子2 3和5的數稱作醜數 ugly number 例如6 8都是醜數,但14不是,因為它包含因子7。習慣上我們把1當做是第乙個醜數。求按從小到大的順序的第n個醜數。分析 為了保證時間達到要求,可以將所求得的醜數都儲存在陣列中,然後再取出。前面的醜數乘以2 3或5中的最小的乙個是下乙個醜數。...