求第N个丑数

原问题描述:

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

这个题不是很难,基本上看完题就能想出解法,但是要想出时间复杂度为O(N)的解法还是有点难度的。我最开始的解法时间复杂度为O(NlgN),后来在网上看到更好的解法时间复杂度为O(N),感觉解法很好,因此在这里分析一下。
我自己的解法就不贴上来了,这里给出别人的解法:

int GetUglyNumber_Solution(int index)
{
        if(index < 7)
            return index;
        vector<int> res(index);
        res[0] = 1;
        int id2 = 0;
        int id3 = 0;
        int id5 = 0;
        for(int i = 1; i < index; ++i)
        {
            res[i] = min(res[id2]*2, min(res[id3]*3, res[id5]*5));
            if(res[i] == res[id2]*2)
                ++id2;
            if(res[i] == res[id3]*3)
                ++id3;
            if(res[i] == res[id5]*5)
                ++id5;
        }

        return res[index-1];
}

时间复杂度:O(N)。
空间复杂度:O(N)。
算法思想:位于后面的丑数必定是前面的丑数与2、3或5的乘积,因此要计算某个位置的丑数值,只要取前面某个位置的丑数与三个质因子的乘积最小值就可以了。
程序用vector来存储前index个丑数(此解法很好的地方之一就是不做多余的动作,从前往后逐个计算丑数,每次计算出的结果不会有非丑数的出现)。
id2、id3、id5三个变量用于存储下标,什么下标?由程序可知,对于i位置的丑数,其值等于res[id2]*2、res[id3]*3、res[id5]*5的最小值,可见,这三个变量就是让i位置的丑数值最小的丑数的下标。
三个存储下标的变量为何要加1?当某个位置的丑数与2、3和5之一的乘积确定了后面的一个丑数后,相应质因子对应的变量肯定得加1了,不然后面会出现重复的丑数值。
注意:这里循环中的三个if语句不能写为if…else if…else语句,因为有可能res[id2]*2、res[id3]*3和res[id5]*5中的某两个甚至三个相等,如果改为if…else if…else语句,那么很有可能在后面还会出现重复的数字。
算法分析完毕,总体思想感觉与斐波那契数列的解法类似,不过这里要稍微复杂一点。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值