1. 程式人生 > >《劍指offer》(面試題34):醜數

《劍指offer》(面試題34):醜數

題目描述

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

解題思路

同樣的,我們首先想到的可能就是遍歷判斷,但是每個數都要計算一次是不是ugly,很是麻煩。於是我們想,能不能只對ugly進行計算呢,顯然是可以的。

我們用一個數組來從小到大存放ugly,那現在的問題就是排序問題了,我們如何來保障這裡面的陣列是排好序的呢?

我們把當前數組裡面最大的ugly記為M,那麼,下一個ugly肯定是前面的數與2或者3或者5的乘積中的最小值。然後我們拿這個最小值和M進行比較,如果小於M,就說明已經存在於陣列中,如果大於M,則說明需要新增進陣列。需要注意的是,我們每次判斷之後,我們只需要第一個比M大的值,其他的以後會重新計算。程式中通過t2、t3、t5分別記錄上次計算用到的ugly的相應序號。

比如現在res中存放的是[1,2,3],此時,t2、t3都為1,t5為0,min(res[1] * 2, min(res[1] * 3, res[1] * 5)) 結果為4,res變為[1,2,3,4],判斷後t2變成2,以此類推。

因為7之前的數(7除外)都是ugly,所以程式一開始的判斷可以和i直接寫index < 7。

python 程式碼實現:
# -*- coding:utf-8 -*-
class Solution:
    def GetUglyNumber_Solution(self, index):
        # write code here
        if index < 7:
            return index;
        res = [1]
        t2 = t3 = t5 = 0
        for i in range(1,index):
            res.append(min(res[t2] * 2, min(res[t3] * 3, res[t5] * 5)))
            if res[i] == res[t2] * 2:
                t2 += 1
            if res[i] == res[t3] * 3:
                t3 += 1
            if res[i] == res[t5] * 5:
                t5 += 1
        return res[-1]