面试题34:丑数

面试题34:丑数

题目

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

暴力解法

从1开始步长为1,逐个判断是否为丑数。效率太低

根据丑数的规则,直接生成丑数序列

假如我们已经有了从1到k的丑数,如何生成k到N的丑数呢?

问题就在于第k+1个丑数是怎么生成的?

一个想法是从第一个丑数开始,依次乘以2、3、5,直到出现大于第k个丑数。

但这样又有很多不必要的计算。

假设我们从第一个丑数开始,依次乘以2、3、5,直到出现大于第k个丑数,此时这个位置能否直接用于第k+2个数的生成呢?而不是每次都从第一个丑数开始计算。

顺着这个思路比较难想清楚。换个思路

每个丑数的出现必定是前面的丑数乘以2或者3或者5。我们先对前面的每个丑数都依次乘以2,直到遇到大于第k个丑数的情况,并记下这个位置;然后对前面的每个丑数都依次乘以3,直到遇到大于第k个丑数的情况,并记下这个位置;然后对前面的每个丑数依次乘以5,直到遇到大于第k个丑数的情况,并记下这个位置。这样我们就有了三个大于第k个丑数的新的丑数,那么谁是第k+1个丑数呢?当然是三者中较小的那个。然后第k+2的丑数可以接着前面的工作来。

public int GetUglyNumber_Solution(int index) {
    ArrayList<Integer> result = new ArrayList<>();
    result.add(1);
    int nextUgly = 0;
    int index2 = 0;
    int index3 = 0;
    int index5 = 0;
    while(index!=result.size()){
        int min = result.get(index2)*2<result.get(index3)*3?result.get(index2)*2:result.get(index3)*3;
        min = min<result.get(index5)*5?min:result.get(index5)*5;
        result.add(min);
        nextUgly++;
        while(result.get(index2)*2<=result.get(nextUgly)){
            index2++;
        }
        while (result.get(index3)*3<=result.get(nextUgly)){
            index3++;
        }
        while (result.get(index5)*5<=result.get(nextUgly)){
            index5++;
        }
    }
    return result.get(index-1);
}

用三个指针的好处就是可以记录进度,想用一个指针完成记录进度的工作是不可能的。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到大的顺序的第1500个丑数。习惯...
    qmss阅读 4,988评论 0 0
  • 题目49:丑数 我们把只包含因子2、3 和5 的数称作丑数(Ugly Number)。求从小到大的顺序的第1500...
    stoneyang94阅读 3,660评论 0 0
  • 1.把二元查找树转变成排序的双向链表 题目: 输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。 要求不...
    曲终人散Li阅读 8,649评论 0 19
  • 这话不是我说的,是朋友转述师长的话,老师的教育方式我们很是羡慕。 他的孩子初中时,一周五天,三天在校,周一周五是一...
    心若芷兰阅读 2,593评论 2 4
  • 答:土米已申请国家专利,现处于实质审查阶段,专利号:201510857148.1 更多详细内容 请加qq55492...
    土米阅读 1,828评论 0 0

友情链接更多精彩内容