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];
    }
}
原文地址:https://www.cnblogs.com/yjxyy/p/10841115.html