JAVA: 丑数

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

分析:

一个数m是另一个数n的因子,是指n能被m整除,也就是m%n==0.

解法一:逐一判断每个数,时间效率很低。

public class Solution {
    //解法一:逐一判断每个数是不是丑数
    public int GetUglyNumber_Solution(int index) {
        if(index<=0)
            return 0;
        int number=0;
        int uglyfound=0;
        while(uglyfound<index){
            ++number;
            if(isUglyNumber(number)){
                ++uglyfound;
            }
        }
        return number;
    }

    public boolean isUglyNumber(int number){
        while(number%2==0)
            number=number/2;
        while(number%3==0)
            number=number/3;
        while(number%5==0)
            number=number/5;
        return (number==1)?true:false;
    }
}

解法二:创建数组保存已经找到的丑数,用空间换时间的思想。

根据丑数的定义,丑数应该是另一个丑数乘以2、3或者5的结果(1除外),因此可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。

但是可以想到的是我们不需要把已有的每个丑数都要乘以2、3或者5,因为已有的丑数在数组中是顺序存放的。对乘以2而言,肯定存在某个丑数T2,它之前的丑数乘以2得到的结果都会小于已有最大的丑数,它之后的丑数乘以2得到的丑数都会大于已有的最大丑数。同理存在T3和T5。因此我们求下一个丑数的时候,只需要考察这3个丑数之间的最小值即可。

public class Solution {
    //解法二:用数组存放丑数,利用空间换时间
    public int GetUglyNumber_Solution1(int index) {
        if(index<=0)    return 0;
        int[] uglyArray=new int[index];
        uglyArray[0]=1;
        int nextuglyIndex=1;
        int Index2=0;
        int Index3=0;
        int Index5=0;
        while(nextuglyIndex<index){
            uglyArray[nextuglyIndex]=minOf3number(2*uglyArray[Index2],3*uglyArray[Index3],5*uglyArray[Index5]);
            while(2* uglyArray[Index2]<=uglyArray[nextuglyIndex])
                Index2++;
            while (3*uglyArray[Index3]<=uglyArray[nextuglyIndex])
                Index3++;
            while(5*uglyArray[Index5]<=uglyArray[nextuglyIndex])
                Index5++;
            nextuglyIndex++;
        }
        return uglyArray[index-1];
    }

    public int minOf3number(int a,int b,int c){
        int min1=(a<b)?a:b;
        int min=(min1<c)?min1:c;
        return min;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值