求第 n 個醜數。醜數序列:1, 2, 3, 4, 5, 6, 8, 9, 10, 12...(質因數僅 2,3,5)。
每個醜數 = 某較小醜數 × 2 或 ×3 或 ×5。維護三個指針 i2, i3, i5 分別指向下一個乘以 2、3、5 產生新醜數的位置:
next2 = ugly[i2] * 2next3 = ugly[i3] * 3next5 = ugly[i5] * 5min(next2, next3, next5)
// Runtime: 9 ms
public class Solution {
public int nthUglyNumber(int n) {
int[] ugly = new int[n];
ugly[0] = 1;
int i2 = 0, i3 = 0, i5 = 0;
for (int i = 1; i < n; i++) {
int next2 = ugly[i2] * 2;
int next3 = ugly[i3] * 3;
int next5 = ugly[i5] * 5;
int next = Math.min(next2, Math.min(next3, next5));
ugly[i] = next;
if (next == next2) i2++;
if (next == next3) i3++;
if (next == next5) i5++;
}
return ugly[n - 1];
}
}
| i | ugly[i] | i2 | i3 | i5 | next2 | next3 | next5 |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 0 | 0 | 0 | 2 | 3 | 5 |
| 1 | 2 | 1 | 0 | 0 | 4 | 3 | 5 |
| 2 | 3 | 1 | 1 | 0 | 4 | 6 | 5 |
| 3 | 4 | 2 | 1 | 0 | 6 | 6 | 5 |
| 4 | 5 | 2 | 1 | 1 | 6 | 6 | 10 |
| 5 | 6 | 3 | 2 | 1 | 8 | 9 | 10 |
| 6 | 8 | 4 | 2 | 1 | 10 | 9 | 10 |
| 7 | 9 | 4 | 3 | 1 | 10 | 12 | 10 |
| 8 | 10 | 5 | 3 | 2 | 12 | 12 | 15 |
| 9 | 12 | 6 | 4 | 2 | 16 | 15 | 15 |
獨立 if 而非 else if,確保 6 = 2×3 = 3×2 時 i2 和 i3 都前進,避免重複生成 6。