求第n个丑数

题目描述:求从小到大的第 N 个丑数。丑数是只包含因子 2、3 和 5 的数,习惯 上我们把 1 当做是第一个丑数。

第一种方法:

从1开始判断下一个数是否是丑数,判断标准:

如果能被2整除则,一直除以2,并用商来更新原来的数,直到不能被2整除记下最终所得数为M2

对于M2如果能被3整除,则一直除以3,并用商来更新原来的数,直到无法被3整除,记下最终所得数为M3

对于M3如果能被5整除,则一直除以5,并用商来更新原来的数,直到无法被5整除,记下最终所得数为M5

如果最终的M5==1那么,这个数是丑数,如此下去直到找到第n个丑数为止

这种方法时间复杂度太大

import java.util.ArrayList;
public class Solution {
public int GetUglyNumber_Solution(int index)
    {
        if (index <= 0)
        {
            return 0;
        }
 
        int number = 0;
        int uglyCount = 0;
 
        while (uglyCount < index)
        {
            number++;
 
            if (IsUgly(number))
            {
                uglyCount++;
            }
        }
 
        return number;
    }
 
    public boolean IsUgly(int number)
    {
        while (number % 2 == 0)
        {
            number /= 2;
        }
 
        while (number % 3 == 0)
        {
            number /= 3;
        }
 
        while (number % 5 == 0)
        {
            number /= 5;
        }
 
        return number == 1 ? true : false;
    }
}

第二种方法:

充分利用已有丑数的信息,下一个要找的丑数比已有最大丑数刚刚大(用一个例子来演示这个过程比较好理解),这样可以得到一个有序的丑数序列

记录丑数序列a中最大的丑数为M,第一个丑数为1

  • 1 a

2 i=0 M2=a[i]*2=2

3 j=0 M3=a[j]*3=3

5 z=0 M5=a[z]*5=5

min(M2,M3,M5)=M2

  • 1 2 a

2 4 i=1 M2=a[i]*2=4

3 6 j=0 M3=a[j]*3=3

5 10 z=0 M5=a[z]*5=5

min(M2,M3,M5)=M3=3

  • 1 2 3 a

2 4 6 i=1 M2=a[i]*2=4

3 6 9 j=1 M3=6

5 10 15 z=0 M5=5

min(M2,M3,M5)=M2=4

  • 1 2 3 4 a

2 4 6 8 i=2 M2=6

3 6 9 12 j=1 M3=6

5 10 15 20 z=0 M5=5

min(M2,M3,M5)=M5=5

import java.util.ArrayList;
public class Solution {
    public int GetUglyNumber_Solution(int index) {
        ArrayList<Integer> out=new ArrayList<Integer>();
        out.add(1);
        if(index<=0){
            return 0;
        }
        int count=0;
        int M2=1,index2=0;
        int M3=1,index3=0;
        int M5=1,index5=0;
        while(count<index){
            out.add(Math.min(Math.min(M2,M3),Math.min(M3,M5)));
            count++;
            while(out.get(index2)*2<=out.get(out.size()-1))
            {index2++;}
            M2=out.get(index2)*2;
            
             while(out.get(index3)*3<=out.get(out.size()-1))
            {index3++;}
            M3=out.get(index3)*3;
            
            while(out.get(index5)*5<=out.get(out.size()-1))
            {index5++;}
            M5=out.get(index5)*5;
        }
        return out.get(out.size()-1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值