题目
把只包含质因子2、3和5的数称作丑数(Ugly Number)。
例如6、8都是丑数,但14不是,因为它包含质因子7。
习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
看到这个问题的时候可以这样想:
解题思路:
因为一个丑数只包含质因子2、3和5,也就是说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到。这里采用以“时间换取空间”的办法,通过构建一个辅助空间,用来存放每次乘2、乘2、乘5的最小值,在判断找丑数的同时也给丑数排序了,方便后面的查找。
代码示例:
/**
* 一个丑数的因子只有2,3,5,也就是说
* 一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到
* 只用比较3个数:用于乘2的最小的数、用于乘3的最小的数,用于乘5的最小的
* @param index
* @return
*/
public int GetUglyNumber_Solution(int index) {
if (index == 0) {
return 0;
}
if(index == 1) {
return 1;
}
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
int i2 = 0, i3 = 0, i5 = 0;
while (list.size() < index) {
int m2 = list.get(i2)*2;
int m3 = list.get(i3)*3;
int m5 = list.get(i5)*5;
int min = Math.min(m2, Math.min(m3, m5));
list.add(min);
if (min == m2) {
i2++;
}
if (min == m3) {
i3++;
}
if (min == m5) {
i5++;
}
}
return list.get(list.size() - 1);
}
总结
时间复杂度为O(n)
这里需要注意的是
- 这种方法可以避免在非丑数的上的计算时间,提高了一定的效率,但是因为要存储已经生成的丑数,因此需要创建一个数组(数组通过下标查找可时间复杂度O(1)),从而增加了空间消耗。