題目:把只包含質因子2、3和5的數稱作醜數(Ugly Number)。例如6、8都是醜數,但14不是,因爲它包含質因子7。 習慣上我們把1當做是第一個醜數。求按從小到大的順序的第N個醜數。
思路:比較直觀的就直接拿過來做除法就行了,但時間複雜度超級大,基本測試時就掛掉了。這裏使用另一種思路來解。
i=f(2、3、5) :
i*1 =(2、3、5)
i*2=(4、6、10)
i*3=(6、9、15)
...
發現如果按i*n的形式排列結果會有重複值並且不會按序排列。這裏我們可以在用到時再去乘相應的2、3、5而不是每次都去做一遍2、、3、5乘以相同的i。所以我們這裏需要使用三個指針來分別控制2、3、5所處的倍數。
/**
* 醜數
*
* @param index
* @return
*/
public int getUglyNumber(int index) {
if (index <= 0) return 0;
int p2 = 0;
int p3 = 0;
int p5 = 0;
int[] result = new int[index];
result[0] =1; // 最小質因子從1開始
for (int i = 1; i < index; i++) {
result[i] = Math.min(result[p2] * 2, Math.min(result[p3] * 3, result[p5] * 5));// 得到指針位置的2、3、5哪個乘數最小
// 移動各自指針保證去重
if (result[i] == result[p2] * 2) p2++;
if (result[i] == result[p3] * 3) p3++;
if (result[i] == result[p5] * 5) p5++;
}
return result[index-1];
}
- 時間複雜度:O(n)。
- 空間複雜度:O(n)。