演算法訓練:Ugly Number II
阿新 • • 發佈:2019-01-25
題目描述:
醜數:因子只含有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