【Java】 剑指offer(49) 丑数

本文参考自《剑指offer》一书,代码采用Java语言。

更多:《剑指Offer》Java实现合集  

题目 

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

思路

  直观思路:逐一判断每个整数是否为丑数,效率太低。

  空间换时间的解法:

  创建数组存放已经排序好的丑数,这将消耗一定的内存开销。根据丑数的定义,丑数应该是另一个丑数的2、3或者5倍的结果,因此,我们从数组中已有的丑数里找到三个丑数T2、T3、T5,它们分别和2、3、5相乘得到的值恰好比已有的最大丑数大,三个乘积中最小的一个就是下一个丑数,存放入数组中,同时更新T2、T3、T5,使它们仍然保持与2、3、5的乘积恰好比已有的最大丑数大。

测试算例 

  1.功能测试(2,3,4,5等)

  2.特殊测试(0,1)

  3.性能测试(1500等)

Java代码

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

public class UglyNumbe {
    public int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        int[] UglyNumbers=new int[index];
        UglyNumbers[0]=1;
        int index2=0;
        int index3=0;
        int index5=0;
        for(int i=1;i<index;i++){
            UglyNumbers[i]=getMinimum(UglyNumbers[index2]*2,UglyNumbers[index3]*3,UglyNumbers[index5]*5);
            while(UglyNumbers[index2]*2<=UglyNumbers[i])
                index2++;
            while(UglyNumbers[index3]*3<=UglyNumbers[i])
                index3++;
            while(UglyNumbers[index5]*5<=UglyNumbers[i])
                index5++;
        }
        return UglyNumbers[index-1];
    }
    
    private int getMinimum(int a,int b,int c){
        if(a>b)
            a=b;
        if(a>c)
            a=c;
        return a;
    }
    
    
   /*逐一判断每个数是否为丑数,效率太低
    public int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        int number=1;
        int count=0;
        while(true){
            if(isUgly(number))
                count++;
            if(count==index)
                return number;
            number++;
        }
    }
    private boolean isUgly(int number){
        while(number%5==0)
            number/=5;
        while(number%3==0)
            number/=3;
        while(number%2==0)
            number/=2;
        return number==1;
    }
   */
}

  

收获

  1.判断m是否为n的因子:即判断n能否被m整除,也就是n%m=0。要掌握判断因子的方法。例如判断丑数的程序如下:

    private boolean isUgly(int number){
        while(number%5==0)
            number/=5;
        while(number%3==0)
            number/=3;
        while(number%2==0)
            number/=2;
        return number==1;
    }

  2.丑数是另一个丑数的2、3或者5倍,要记住这类特性和规律。特别是在遇到类似的新概念时。

更多:《剑指Offer》Java实现合集  

  

原文地址:https://www.cnblogs.com/yongh/p/9952218.html