• 剑指offer-第5章优化时间和空间效率(丑数)


    题目:我们把只包含因子2,3,5的数叫做丑数。寻找第1500个丑数。通常把1当成第一个丑数。

    思路1:第一步判断是否为丑数:丑数是只包含2,3,5的数,因此一定可以被2,3,5整除。通过求余数是否为零做为判断条件,通过除以来减小整个数的值,知道整个数为1.返回true.

    第二步找到第N个丑数的值,这一种做法的缺点是,不是丑数的数也要求余数除数的运算,因此耗时。因此我们提出一种以空间换时间的方法(谁让如今硬件更新的快呢)。如2思路。

    思路2:我采用一个数组按照从小到大的顺序存放丑数。数组中最后一个放入的丑数即是最大的丑数M。然后,将M之前的数分别乘以,2,3,5来找到下一个大于M的丑数。改变M的值为最后找的的丑数。在2乘以M之前的丑数的时候一定存在某个丑数在它之前的数和2相乘都小于M,之后的数都大于M。我们可以记录下这个数。并且更新它。就可以很快的找到和2相乘大于M的那个丑数了。

    Java代码思路1:

    //思路:第一步:判断一个数是否为丑数。由于丑数是只包好2,3,5的因子的数,因此我们自然就想到了判断一个丑数先对2进行求余数如果为0再对它进行求除数减小数的大小,
    //同样对3,和5也一样,最后如果结果为1就返回true。第二步,通过判断是否为丑数来数出第N个丑数对应的值。
    public class FindUglyNumber {
        //判断一个数是不是丑数
        public boolean isUgly(int number){
            if(number<=0)
                return false;
            while(number%2==0)
                number/=2;
            while(number%3==0)
                number/=3;
            while(number%5==0)
                number/=5;
            return (number==1)?true:false;
        }
        public int uglyNumber(int uglyNumber){
            if(uglyNumber<=0)
                return 0;
            int ugly=0;//记录丑数的个数
            int number=0;//记录数字
            while(ugly<uglyNumber){
                number++;
                if(isUgly(number))
                    ugly++;
            }
            return number;
        }
        public static void main(String[] args){
            FindUglyNumber findUglyNumber=new FindUglyNumber();
            int uglyNumber=findUglyNumber.uglyNumber(3);
            System.out.println(uglyNumber);
        }
    
    }

    Java代码思路2:

    //思路:将uglyNumber按照从小到大的顺序保存在数组中。因为uglyNumber是只包含2,3,5因子的数,
    //因此可以用一个M表示数组中最大的数,也是数组中最后一个存入的数,而将之前的丑数分别乘2,3,5,然后保留大于M值的最小数。
    //作为下一个M。我们前面说,M之前的每一个丑数都乘以2,3,5,其实这个可以确定在乘以2时在一定存在某个值,在它之前的数都小于M
    //在它之后的数都大于M。
    public class FindUglyNumber1 {
       public int findUglyNumer(int index){
           int[] uglyNumber=new int[index];
           uglyNumber[0]=1;
           int nextNumber=1;
           int nextNumber2=0;
           int nextNumber3=0;
           int nextNumber5=0;
           while(nextNumber<index){
               int min=min(uglyNumber[nextNumber2]*2,uglyNumber[nextNumber3]*3,uglyNumber[nextNumber5]*5);
               uglyNumber[nextNumber]=min;
               while(uglyNumber[nextNumber2]*2<=uglyNumber[nextNumber])
                   nextNumber2++;
               while(uglyNumber[nextNumber3]*3<=uglyNumber[nextNumber])
                   nextNumber3++;
               while(uglyNumber[nextNumber5]*5<=uglyNumber[nextNumber])
                   nextNumber5++;
               nextNumber++;
           }
           int ugly=uglyNumber[nextNumber-1];
           return ugly;
       }
    
    public int min(int i, int j, int k) {
        int min=i<j?i:j;
        return min<k?min:k;
    }
    public static void main(String[] args){
        FindUglyNumber1 findUglyNumber=new FindUglyNumber1();
        int uglyNumber=findUglyNumber.findUglyNumer(3);
        System.out.println(uglyNumber);
    }
    
    }
  • 相关阅读:
    linux中awk命令提取连续列
    re.sub()用法的详细介绍
    pygame教程
    基于 HTML5 和 CSS3 开发的优秀应用程序
    KISSYUI的表单前端js验证和JQuery扩展插件Validate
    提供源码 后台界面WebUi框架分享
    推荐10款非常优秀的HTML5开发工具
    产品化思维之用户认证和用户授权
    JAVA虚机查找class 的规则
    产品化思维之基于资源属性的权限控制方案(ABAC)
  • 原文地址:https://www.cnblogs.com/hupp/p/4758071.html
Copyright © 2020-2023  润新知