33、丑数

题目描述

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

leetcode对应题目:264、丑数II                    题目解答

总结:
”只包含质因子2、3、5的数称作丑数”,说明丑数都是由这三个基数相乘而来。
An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
每一个新的丑数由一个更小的丑数乘以2、3、5得到。所以可以想象三个“链表”和三指针,第一个链表只做乘2操作,第二个乘3、第三个乘5。
定义一个vector来存放已经生成的丑数,题目给出第一个丑数为1。
    (1) 1x2,  2x2, 2x2, 3x2, 3x2, 4x2, 5x2
    (2) 1x3,  1x3, 2x3, 2x3, 2x3, 3x3, 3x3
    (3) 1x5,  1x5, 1x5, 1x5, 2x5, 2x5, 2x5
    min  2     3    4    5    6    ......
    对应的数组(1,2,3,4,5,6,...)
    丑数1可以根据乘以2,乘以3,乘以5,分别得到三个不同的丑数,因为题目给出“按照从小到大的顺序”,所以我们每一步只能抉择出一个新的丑数,选择min(2,3,5)最小的一个作为新的丑数,即2,添加到数组之中[1,2],此时1这个丑数已经用基数 2 生成了新的丑数,指针位置向后挪动一位,index2++ ; 但是此时1这个丑数,对应的基数3,5并没有生成新的丑数,所以仍然保留,即链表2和链表3的丑数不改变(对应的指针位置不改变),下一次循环,三个链表生成的新丑数为min(4,3,5),即链表2产生的3添加到丑数数组之中,丑数数组变成[1,2,3],此时链表2一开始对应的丑数1已经使用过了,应该向后挪动一位,改用丑数2.同理循环下去。要注意,因为肯定会出现生成的某个新丑数和两个链表产生的丑数相等:也就是2*3,3*2,这种情况。如果我们用if...else...则会引起重复,所以条件的判断是if...if...if...如果某个链表产生的丑数和选中的最小丑数一致,就应该把当前指针向后挪动一位;选取数字乘以基础是从丑数数组中选,而不是加一,如下图就是错误的:

一开始计算的都是正确的,因为丑数数组正好是累加增长,但是后面选取7,7X2 = 14就不是丑数了,所以是从丑数数组中选取。

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        if(index == 0)    return 0;
        vector<int> res{1};
        int index2 = 0,index3 = 0,index5 = 0;
        while(res.size() != index){
            int a = res[index2] * 2 , b = res[index3] * 3,c = res[index5] *5;
            int min_val = min(a,min(b,c));
            if(a == min_val)    index2++;
            if(b == min_val)    index3++;
            if(c == min_val)    index5++;
            res.push_back(min_val);
        }
        return res.back();
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值