题目描述:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
题解:
每一个丑数分别乘【2,3,5】可以产生3个丑数。
p2=[2]
p3=[3]
p5=[5]
对以上数据,我们进行几次迭代:
(1)先将第一列的每个数乘以2:
- p2=[2,4]
- p3=[3,6]
- p5=[5,10]
(2)将第二列每个数乘以3:
- p2=[2,4,6]
- p3=[3,6,9]
- p5=[5,10,15]
(3)将第二列每个数乘以5:
- p2=[2,4,6,10]
- p3=[3,6,9,15]
- p5=[5,10,15,25]
再接着将第二列数字乘以2,3,5
第三列数字乘以2,3,5
……
但这样复杂度较高,而且会得到重复的丑数。
实际上每次我们只用比较3个数:用于乘2的最小的数、用于乘3的最小的数,用于乘5的最小的数。这样只需要维护三个指针,而不用维护三个数组。
public static int GetUglyNumber_Solution(int index) {
if(index <= 0){
return 0;
}
// 三个指针定位
int p2 = 0;
int p3 = 0;
int p5 = 0;
int[] result = new int[index];
result[0] = 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];
}