一、题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
二、解题思路
根据丑数的定义,丑数只能被2、3和5整除。因此一个丑数是另一个丑数乘以2、3或者5的结果(1除外)。基于此可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。
思路关键在于丑数数组的排序,可以定义三个指针,比较当前丑数分别乘以2、3和5之后值的大小,只存入最小值并移动对应指针。
例如:
丑数数组:{1}
指针i2=0,1×2=2
指针i3=0,1×3=3
指针i5=0,1×5=5
最小值为2,放入数组,指针i2++
丑数数组:{1,2}
指针i2=1,2×2=4
指针i3=0,1×3=3
指针i5=0,1×5=5
最小值为3,放入数组,指针i3++
丑数数组:{1,2,3}
指针i2=1,2×2=4
指针i3=1,2×3=6
指针i5=0,1×5=5
最小值为4,放入数组,指针i2++
丑数数组:{1,2,3,4}
指针i2=2,3×2=6
指针i3=1,2×3=6
指针i5=0,1×5=5
最小值为5,放入数组,指针i5++
…直至找到第n个丑数
三、编程实现
public class Solution {
public int GetUglyNumber_Solution(int index) {
if (index <= 0) {
return 0;
}
int[] result = new int[index];
// 定义三个指针
int count, i2, i3, i5, temp;
count = i2 = i3 = i5 = 0;
result[0] = 1;
while (count < index - 1) {
// 比较当前丑数分别乘以2、3和5之后值的大小,只存入最小值并移动对应指针
temp = Math.min(result[i2] * 2, Math.min(result[i3] * 3, result[i5] * 5));
if (temp == result[i2] * 2) {
i2++;
}
if (temp == result[i3] * 3) {
i3++;
}
if (temp == result[i5] * 5) {
i5++;
}
result[++count] = temp;
}
return result[index - 1];
}
}