1. 程式人生 > >演算法訓練:Ugly Number II

演算法訓練:Ugly Number II

題目描述:

   醜數:因子只含有2,3,5的數,例如2,3,5,6,8等。要求返回第n個醜數。

解題思路:

     從1開始判斷一個數是否為醜數,若是計數加1,一直到計數等於n,返回該數字

   bool isUgly(int num) {
        
        if (num <= 0) {
            return false;
        }
        //判斷num的因子是否只含2,3,5
        while (num % 2 == 0) num /= 2;
        while (num % 3 == 0) num /= 3;
        while (num % 5 == 0) num /= 5;
        
        if (num == 1) {
            return true;
        } else {
            return false;
        }
    }

    int nthUglyNumber(int n) {
        if (n <= 1) {
            return 1;
        }

        int count = 0;
        for (int i = 1; ; i++) {
            
            if (isUgly(i)) {
                count++;
                if (count == n) {
                    return i;
                }
            } 
        }
    }
    動態規劃的方法:

       醜數序列可以拆分為下面3個子列表:

         factor=2: 1×2, 2×2, 3×2, 4×2, 5×2,...

         factor=3: 1×3, 2×3, 3×3, 4×3, 5×3, …

         factor=5: 1×5, 2×5, 3×5, 4×5, 5×5, …

       觀察上述三個列表,可以發現每個子列表都是一個醜數分別乘以2,3,5。

       分別用t2,t3,t5來記錄當前三個序列的下標,然後比較三者,最小的數先加入醜數序列

       邊界條件:result[0]=1。

       推導式:result[i]=min(result[t2]*2,result[t3]*3,result[t5]*5),result[i]儲存的是第i+1個

醜數。

    int nthUglyNumber(int n) {
        if(n <= 0) return 0;
	vector<int> result(n, 1); //全部初始化為1
	int t2 = 0, t3 = 0, t5 = 0; //初始下標均從0開始
	for(int i = 1; i < n; ++i){
	   result[i] = min(result[t2]*2, min(result[t3]*3, result[t5]*5));
	   if(result[i] == result[t2]*2) t2++; //判斷是否是factor=2的序列對應的下標需要向後移動
	   if(result[i] == result[t3]*3) t3++;
	   if(result[i] == result[t5]*5) t5++;
	}
	return result[n-1];
    }

執行結果:

Your Input
10
Your answer
12
Expected answer
12