33.丑数
题目描述:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路分析:
最小的丑数是1,因为丑数只包含质因子2,3,5,那么我们可以知道一个丑数肯定等于另外一个丑数乘以2,或者3,或者5,那么我们给1乘以2,3,5得到了丑数2,3,5,这时我们有可以分别给每个数字乘以2,3,5得到更大的丑数,题目要求的是从小到大顺序的第N个丑数。那么我们可以维护三个队列:
(1)丑数数组:1
乘以2的队列:2
乘以3的队列:3
乘以5的队列:5
选择三个队列头中最小的数加入丑数数组,并且将这个最小的数乘以2,3,5,加入三个队列。
(2)丑数数组:1,2
乘以2的队列:4
乘以3的队列:3 6
乘以5的队列:5 10
选择三个队列头最小的数3加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;
(3)丑数 数组:1,2,3
乘以2的队列:4 6
乘以3的队列:6 9
乘以5的队列:5 10 15
就这样最后取到第N个丑数。但是在实际的实现过程中我们没必要设置三个队列,只需要设置三个指针i2,i3,i5 记录分别走到哪一步。
(1)1
|2
|3
|5
目前指针指向0,0,0,队列头arr[0]2=2,arr[0]3=3,arr[0]*5=5,所以取2进入丑数数组
(2)1,2
2|4
|3 6
|5 10
目前指针指向1,0,0,队列头arr[1]2=4,arr[0]3=3,arr[0]*5=5,所以取3进入丑数数组
(3)1,2,3
2|4
3| 6
|5 10
目前指针指向1,1,0,队列头arr[1]2=4,arr[1]3=6,arr[0]*5=5,所以取3进入丑数数组
.....
代码:
public class Solution {
public int GetUglyNumber_Solution(int index) {
if(index<1)
return 0;
int i2=0; //指针维护乘2队列
int i3=0; //指针维护乘3队列
int i5=0; //指针维护乘5队列
int []array=new int[index]; //丑数数组
array[0]=1; //第一个丑数为1
int count=0; //记录丑数的的个数
while(count<index-1){
int temp=Math.min(array[i2]*2,Math.min(array[i3]*3,array[i5]*5));//取三个队列头中最小的数
if(array[i2]*2==temp)i2++;
if(array[i3]*3==temp)i3++;
if(array[i5]*5==temp)i5++;
array[++count]=temp; //将三个队列头中最小的数放进丑数数组。
}
return array[index-1];
}
}