《剑指offer—面试题49:丑数》

《剑指offer—面试题49:丑数》
注明:仅个人学习笔记

————————————-方法一:注释1———————————-
/**方法一,用空间换时间
*
* 用一个数组去保存丑数,再在丑数中去找需要的第几个丑数
*
*/
public class GetUglyNumber49_2
{
public int GetUglyNumber_Solution(int index)
{

    if (index <= 0)
    {
        return 0;

    }

    int[] pUglyNumbers = new int[index];
    pUglyNumbers[0] = 1;
    int nextUglyIndex = 1;

    int index2 = 0;
    int index3 = 0;
    int index5 = 0;

    while (nextUglyIndex < index)
    {

        // 生成丑数时,每次不用同一个数同时乘以2,3,5
        //Min中这三个数在未插入丑数数组之前,都是大于当前丑数数组中的最大值的,因为丑数数组有序,所以我们需要这三个丑数中最小的一个作为新生成的丑数
        int min = Min(pUglyNumbers[index2] * 2, pUglyNumbers[index3] * 3, pUglyNumbers[index5] * 5);
        pUglyNumbers[nextUglyIndex] = min;// 这个数也同时表示当前丑数数组中的最大数
        int curMax = pUglyNumbers[nextUglyIndex];//也就是offer书中所设的M


        /**
         * //这里不能用elseif,因为可能有两个最小值,这时都要挪动,比如3*2 = 6,到了2*3 = 6。(应该是这个意思)
         */
        // 因为丑数数组中的数是有序的,由于我们是按照顺序生成的,小于或者等于curMax肯定已经在数组中了,
        // 说明当前pUglyNumbers[index2]这个数已经乘过2了,并且乘以2得到的数已经在丑数数组中了,所以有index2++,该下一个数去乘以2了
        while (pUglyNumbers[index2] * 2 <= curMax)
            ++index2;
        // 说明当前pUglyNumbers[index3]这个数已经乘过3了,并且乘以3得到的数已经在丑数数组中了,所以有index3++,该下一个数去乘以3了
        while (pUglyNumbers[index3] * 3 <= curMax)
            ++index3;
        // 说明当前pUglyNumbers[index5]这个数已经乘过5了,并且乘以5得到的数已经在丑数数组中了,所以有index5++,该下一个数去乘以5了
        while (pUglyNumbers[index5] * 5 <= curMax)
            ++index5;

        ++nextUglyIndex;
    }

    int ugly = pUglyNumbers[nextUglyIndex - 1];

    return ugly;

}

// 三个数中确定最小数
private int Min(int number1, int number2, int number3)
{
    int min = (number1 < number2) ? number1 : number2;
    min = (min < number3) ? min : number3;

    return min;
}

public static void main(String[] args)
{
    GetUglyNumber49_2 u = new GetUglyNumber49_2();

    int ugly = u.GetUglyNumber_Solution(1500);

    System.out.println(ugly);
}

}

————————————-方法一:注释2———————————-
public class test49
{
public int getUglyNumber(int index)
{
if (index < 0)
{
return 0;
}

    int[] uglyNumbers = new int[index];
    uglyNumbers[0] = 1;
    int nextIndex = 1;

    int index2 = 0;
    int index3 = 0;
    int index5 = 0;

    while (nextIndex < index)
    {

        // step1 生成丑数
        int M2 = uglyNumbers[index2] * 2;
        int M3 = uglyNumbers[index3] * 3;
        int M5 = uglyNumbers[index5] * 5;

        // step2 因为丑数数组有序,从小到大排序,所以选出生成的丑数中最小的添加到丑数数组中
        int min = Min(M2, M3, M5);
        uglyNumbers[nextIndex] = min;

        // 同时获得此时丑数数组中的最大丑数
        int curUglyMax = uglyNumbers[nextIndex];

        // step3 选择由哪些数用来生成下一批丑数
        // 原则是,已经生成过某个倍数的丑数的数,其生成的丑数已经添加进数组,就不再用来生成相同倍数的丑数了,改由其下一个数去生成对应倍数的丑数
        // 其生成的某个倍数的丑数仍未添加进数组,那继续由该数生成对应倍数的丑数
        while (uglyNumbers[index2] * 2 <= curUglyMax)
            index2++;

        while (uglyNumbers[index3] * 3 <= curUglyMax)
            index3++;

        while (uglyNumbers[index5] * 5 <= curUglyMax)
            index5++;

        // step4 取得添加下一个丑数的索引
        nextIndex++;

    }

    // 最后,数组中的最后一个元素即为所求
    int ugly = uglyNumbers[index - 1];

    return ugly;

}

// 三个数中求最小
private int Min(int number2, int number3, int number5)
{
    int min = (number2 < number3) ? number2 : number3;
    min = (min < number5) ? min : number5;

    return min;
}

public static void main(String[] args)
{
    GetUglyNumber49_2 u = new GetUglyNumber49_2();

    int ugly = u.GetUglyNumber_Solution(1500);

    System.out.println(ugly);
}

}
——————————-分割线:方法二,暴力查找—————————————–
/**
* 方法二
*
* 我们把只包含因因子2、3、5的数,称为丑数
*
*/
public class GetUglyNumber49
{
public static int GetUglyNumber_Solution(int index)
{
if (index <= 0 || index > Integer.MAX_VALUE)
{
return 0;// 表示不存在
}

    int number = 0;
    int uglyFound = 0;

    while (uglyFound < index)
    {
        ++number;

        if (isUgly(number))
        {
            ++uglyFound;
        }
    }

    return number;

}

private static 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;
}

public static void main(String[] args)
{
    int ugly = GetUglyNumber_Solution(1500);

    System.out.println(ugly);
}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值