《剑指offer》-[第5章:优化时间与空间效率-5.2:时间与空间效率的平衡]-题34:丑数

1、问题描述

我们把只包含因子2、3、5的数称之为丑数,求按照从小到大顺序的第1500个丑数。例如6、8都是丑数,而14不是,因为它的因子包含7,我们习惯上把1作为第一个丑数。

2、解题思路

  • 边界条件:无;
  • 思路1:使用变量count统计丑数的个数,uglynumber记录当前最新的那个丑数,count初始值设置为0,uglynumber设为1。对于从1开始的每一整数N,判断其是否为丑数,如果是,则count加1,当count达到1500的时候,循环停止,输出uglynumber,该方法的核心是如何判断整数N是否为丑数。判断整数N是否为丑数:丑数只能被2、3、5整除,如果N能整除2,则连续除以2;如果能整除3则连续除以3;如果能整除5,则连续除以5。如果最后得到的是1,则该数是整数,否则不是。
  • 思路2:上面这个方法,效率低下是因为对于是不是丑数的整数都要计算一遍,但其实我们只需要计算丑数,而不用考虑非丑数,因为大的丑数一定是由小的丑数构造而来的(×2或3或5)。因此,我们可以创建一个数组,数组里的数字是按照从小到大的顺序排好序的丑数。假设数组中最大的数是M,如果将M前面的每一个丑数乘以2,肯定有一部分是小于M的,另一部分是大于M的,设×2大于M的第一个数的索引为 T 2 T_{2} T2,同理可以得到 T 3 T_{3} T3 T 5 T_{5} T5,那么最后,M后面的首个丑数一定是 2 a [ T 2 ] 2a[T_{2}] 2a[T2] 3 a [ T 3 ] 3a[T_{3}] 3a[T3] 5 a [ T 5 ] 5a[T_{5}] 5a[T5]中的最小值next, 将next扩充到数组中,并进行新一轮的循环,直到数组的长度为1500为止,那么数组最后一个数就是第1500个丑数。注意,在新的一轮循环,查找新的 T i T_{i} Ti时,起始位置只需从 T i T_{i} Ti开始,因为 T i T_{i} Ti前半部分的数乘以 i i i肯定小于新的M(其实就是next)。

3、代码实现

import java.util.ArrayList;

public class Problem_34 {
    public int GetUglyNumber_Solution(int index) {
        if(index <= 0){
            return 0;
        }
        ArrayList uglyarray = new ArrayList();
        uglyarray.add(1);
        Integer T2 = 0;
        Integer T3 = 0;
        Integer T5 = 0;
        while (uglyarray.size() != index){
            Integer M = uglyarray.get(uglyarray.size()-1);

            for (int j = T2;j < uglyarray.size();j++){
                if(uglyarray.get(j) * 2 > M){
                    T2 = j;
                    break;
                }
            }

            for (int j = T3;j < uglyarray.size();j++){
                if(uglyarray.get(j) * 3 > M){
                    T3 = j;
                    break;
                }
            }
            for (int j = T5;j < uglyarray.size();j++){
                if(uglyarray.get(j) * 5 > M){
                    T5 = j;
                    break;
                }
            }

            Integer next  = uglyarray.get(T2) * 2;
            if(uglyarray.get(T3) * 3 < next){
                next = uglyarray.get(T3) * 3;
            }
            if(uglyarray.get(T5) * 5 < next){
                next = uglyarray.get(T5) * 5;
            }

            uglyarray.add(next);

        }
        return uglyarray.get(uglyarray.size() - 1);
    }
}

你可能感兴趣的:(数据结构与算法)