题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
分析
看了别人的思路, 感觉挺抽象, 自己又总结了一下…
- 根据已有的丑数数组data, 通过乘上2,3,5, 去生成新的丑数
[1] -> [1,2] -> [1,2,3] - 有3个指针p_2, p_3, p_5, 被指向的数会乘2,3,5, 每个指针都要遍历已有丑数数组, 这样就能保证不漏
- min(data[p_2]*2, data[p_3]*3, data[p_5]*5)选出最小的作为新的丑数
- 生成新的丑数的指针++, 开始去乘下一个
模拟流程
[1]
p_2 = 0 * (*
表示这个指针生成了新的丑数)
p_3 = 0
p_5 = 0
[1,2]
p_2 = 1
p_3 = 0 *
p_5 = 0
[1,2,3]
p_2 = 1 *
p_3 = 1
p_5 = 0
[1,2,3,4]
p_2 = 2
p_3 = 1
p_5 = 0 *
[1,2,3,4,5]
p_2 = 2 *
p_3 = 1 *
p_5 = 1
[1,2,3,4,5,6]
p_2 = 3 *
p_3 = 2
p_5 = 1
[1,2,3,4,5,6,8]
p_2 = 4
p_3 = 2
p_5 = 1
代码
import java.util.*;
class Solution {
public int nthUglyNumber(int n) {
if(n<=0) return 0;
int[] data = new int[n];
// 初始化第1个
data[0] = 1;
// 3个指针
int p_2 = 0;
int p_3 = 0;
int p_5 = 0;
// 遍历生成
for(int i=1;i<n;++i){
// 新的丑数
int min_ = Math.min(data[p_2]*2,Math.min(data[p_3]*3,data[p_5]*5));
// 指针们更新
if(data[p_2]*2==min_) p_2++;
if(data[p_3]*3==min_) p_3++;
if(data[p_5]*5==min_) p_5++;
data[i] = min_;
}
//System.out.println(Arrays.toString(data));
return data[n-1];
}
}