【Java面试题】丑数

【题目】:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

【示例】:
括号内不是丑数

1 , 2 , 3 , 4 , 5 , 6 ,(7), 8 , 9 , 10 ,(11), 12 ,(13,14), 15

根据上述可以发现: 1乘以 (2、3、5)=2、3、5;2乘以(2、3、5)=4、6、10;3乘以(2、3、5)=6,9,15;5乘以(2、3、5)=10、15、25;这些数是丑数。

思路:

丑数能够分解成2x * 3y * 5z , 难点:顺序。

一个丑数成以2/3/5,得到的还是一个丑数;可以设置三个数组分别存放,介于维护成本这里设置三个指针p2/p3/p5;每次都取最小的数,放到数组中,【小于7的数都是丑数】。

在2x,3y,5z中,如果x=y=z那么最小丑数一定是乘以2的,但关键是有可能存在x>y>z的情况,所以我们要维持三个指针来记录当前乘以2、乘以3、乘以5的最小值,然后当其被选为新的最小值后,要把相应的指针+1。

【关键点】: 穷举

【Java】:

public class Solution {
    //1,2,3,4,5,6,(7),8,9,10,(11),12,(13,14),15,
    public int GetUglyNumber_Solution(int index) {
        if(index<=0) return 0;
        int p2=0,p3=0,p5=0;//初始化三个指向三个潜在成为最小丑数的位置
        int[] uglyNumber = new int[index];//数组大小
        uglyNumber[0] = 1;
        for(int i=1; i < index; i++){
            //第i个丑数:为p2,p3,p5对应的最小数
            uglyNumber[i] = Math.min(uglyNumber[p2]*2, Math.min(uglyNumber[p3]*3, uglyNumber[p5]*5));
            //第i个丑数:为2的倍数,p2+1;下次循环为p2为1,uglyNumber[p2]*2==4;不是倍数就跳过;
            if(uglyNumber[i] == uglyNumber[p2]*2)p2++;
            //第i个丑数:为3的倍数,p3+1;下次循环为p3为1,uglyNumber[p3]*2==6;
            if(uglyNumber[i] == uglyNumber[p3]*3)p3++;
            //第i个丑数:为3的倍数,p3+1;下次循环为p3为1,uglyNumber[p3]*2==10;
            if(uglyNumber[i] == uglyNumber[p5]*5)p5++;
        }
        return uglyNumber[index-1];
    }
}
发布了195 篇原创文章 · 获赞 335 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/cungudafa/article/details/102222380