【题目描述】
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
时间限制:1秒 空间限制:32768K 热度指数:265042
本题知识点: 数组
【思路分析】
法一:暴力求解法
- 了解并书写判断一个数是不是丑数的规则;
- 从1开始,依次判断是否为丑数,是则丑数计数器++,直到计数器的值为要求的值。
此种解法需要对从1开始的每一个数进行验证,做了些无用功。
法二: 利用丑数的生成规则
依据丑数的定义,我们知道 每一个丑数可以由 排在其前面的丑数乘以2、乘以3 或 乘以5构成 。故我们可以依次按照递增顺序生成丑数。下面就需要考虑如何递增生成丑数:
- 1是第一个丑数;
- 第二个丑数为 min(1 * 2, 1 * 3, 1 * 5) = 2;
- 第三个丑数为 min(1 * 2, 1 * 3, 1 * 5, 2 * 2, 2 * 3, 2 * 5) = 3;
- 第四个丑数为 min(1 * 2, 1 * 3, 1 * 5, 2 * 2, 2 * 3, 2 * 5, 3 * 2, 3 * 3, 3 * 5) = 5;
- 第三个丑数为 min(1 * 2, 1 *3 , 1 * 5, 2 * 2, 2 * 3, 2 * 5, 3 * 2, 3 *3 , 3 * 5, 5 * 2, 5 * 3, 5 * 5) = 4;
经过分析:
- 在求第三个丑数时 1 * 2 这一项是无用的(已经用过了),所以在每找到一个丑数时,其对应的指针应该++;
- 在求第三个丑数时, 2 * 3, 2 * 5 这两项一定大于 1 * 3, 1 * 5这两项,故 2 * 3, 2 * 5 可省略。
故,以上可简化为:
- 1是第一个丑数;
- 第二个丑数为 min(1 * 2, 1 * 3, 1 * 5) = 2;
- 第三个丑数为 min(2 * 2, 1 * 3, 1 * 5) = 3;
- 第四个丑数为 min(2 * 2, 2 * 3, 1 * 5) = 5;
- 第三个丑数为 min(2 * 2, 2 * 3, 2 * 5) = 4;
代码如下:
import java.util.ArrayList;
import java.lang.Math;
public class Solution {
// 30ms 9324K
public int GetUglyNumber_Solution(int index) {
// 1 2 3 4 5 6
if(index < 7)
return index;
// list用于按照递增顺序存储丑数
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
int v2 = 0,v3 = 0,v5 = 0;
while(list.size() < index){
int num2 = list.get(v2) * 2;
int num3 = list.get(v3) * 3;
int num5 = list.get(v5) * 5;
int min = Math.min(num2, Math.min(num3, num5));
list.add(min);
if(min == num2)
v2++;
if(min == num3)
v3++;
if(min == num5)
v5++;
}
return list.get(list.size()-1);
}
}