《剑指offer》刷题——【时间效率与空间效率的平衡】面试题49:丑数(java实现)

一、题目描述

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

二、题目分析

方法一:逐个判断每个整数是不是丑数

  • 丑数:只能被2,3,5整除的数
  • 按顺序判断每个整数是不是丑数
  • 判断丑数:连续除以2,连续除以3,连续除以5;若最后得到1,则为丑数

方法二:借助数组保存已找到的丑数,空间换时间

  • 借助大小为N的数组,此数组存放排好序的丑数(每个丑数都是前面的丑数乘以2,3,5得到)
  • 如何确保数组里丑数排好序:
    • 假设已有若干排好序的丑数,其中最大设为M
    • 下一个丑数:
    • 把已有的每个丑数 x 2,得到若干 < = >M的丑数
    • 小于等于的已经在数组中,不用考虑
    • 找到大于M的数中最小的数字,作为下一个丑数
    • x2、x3、x5大于M的数分别记为M2,M3,M5,则下一个数字为这三者中最小的一个
    • 不用把已有的丑数每个都乘以2,3,5,记录通过x2得到的最大的丑数位置,x3,x5的位置上亦是如此,以后确定下一个丑数只需从标记的三个位置的数乘以2,3,5

三、代码实现

public class Solution {
    //假定N的最大值为1500
    private int[] data = new int[1500];
    public int GetUglyNumber_Solution(int index) {
        //错误输入
        if(index<=0)
            return 0;
        //第一个数为丑数
        data[0]=1;
        //设置三个指针,分别表示当前可以获得下个丑数的基数的位置
        int i2 = 0;
        int i3 = 0;
        int i5 = 0;
        //获取下一个丑数
        int currentIndex = 1;
        int next = data[0];
        while(currentIndex < index){
            //计算下一个丑数
            next = min(data[i2]*2, data[i3]*3, data[i5]*5);
            if(data[i2]*2 <= next){
                i2++;
            }
            if(data[i3]*3 <= next){
                i3++;
            }
            if(data[i5]*5 <= next){
                i5++;
            }
            data[currentIndex++] = next;
        }
        return next;
    }
    /**
    * 求三个数字中最小的数
    */
    public int min(int a, int b, int c){
        int min = a<b? a:b;
        min = min < c? min:c;
        return min;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值