• 【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实现合集  

      

  • 相关阅读:
    分析facebook的AsyncDisplayKit框架,async-display使用async-transaction
    自制反汇编逆向分析工具 迭代第四版本
    自制反汇编逆向分析工具 迭代第三版本
    自制反汇编逆向分析工具 迭代第二版本
    分析facebook的AsyncDisplayKit框架中的Transaction的工作原理
    Oracle索引知识学习笔记
    PDF文件添加二维码水印教程
    图片添加二维码水印教程
    CAS单点登录之支持数据库认证
    CAS单点登录之服务端部署
  • 原文地址:https://www.cnblogs.com/yongh/p/9952218.html
Copyright © 2020-2023  润新知