题目:把只包含质因子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)。