五木的第一篇CSDN博客

第一次开始学习用MarkDown编辑器写博客,第一感觉是怎么落入了Web前端开发的感觉!
第一篇博客就随意记录一下今天的算法编程题

求按从小到大的顺序第N个丑数

题目描述

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

C++代码块

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
         if(index < 7) return index;
        //p2,p3,p5分别为三个队列的指针,newNum为从队列头选出来的最小数
        int p2 = 0, p3 = 0, p5 = 0, newNum = 1;
        queue<int> a;//存放每次乘2得到的丑数的队列
        queue<int> b;//存放每次乘3得到的丑数队列
        queue<int> c;//存放每次乘5得到的丑数队列
        vector<int> v;
        while(v.size()!=index){
            if(v.size()==0){
                v.push_back(newNum);
                a.push(newNum*2);
                b.push(newNum*3);
                c.push(newNum*5);
                ;
            }
            else{
                int minnum=min(min(a.front(),b.front()),min(a.front(),c.front()));
                if(a.front()==minnum) {
                    a.pop();
                }
                if(b.front()==minnum){
                    b.pop();
                }
                if(c.front()==minnum){
                    c.pop();
                }
                v.push_back(minnum);
                 a.push(minnum*2);
                 b.push(minnum*3);
                 c.push(minnum*5);
                
            }
        }
        return v[v.size()-1];
}
};

算法思想

  由于丑数只能是质因子含2、3、5的质因子,所以我们可以理解为每一个丑数都是由某一个较小的丑数乘未知个2或者3或者5得到的。所以本题可以采用模拟法,从1开始从小到大模拟生成丑数,直到生成的轮次等于N,此时生成的丑数即为第N个丑数。
  模拟采用三个队列a、b、c和一个存放丑数的数组v。每生成一个新丑数后,用其分别乘2、3、5放入a、b、c 中。并把这个新生成的丑数放入丑数数组v。
  那么如何生成新丑数?通过每次弹出三个队列中队首元素的最小值,这个最小值即为新生成的丑数。如果这个最小值属于多个队列,那么就都弹出。
  通过以上过程,可以得出两个结论。1.同一个队列中的元素按从小到大排列并且没有重复。2.在丑数数组中,新生成加入的丑数必然大于已经存放于丑数数组的元素,且必然不会有重复生成的丑数。当生成N次丑数时,此时的丑数即为所求。
  例如:生成1放入丑数数组,将 1 ∗ 2 1*2 12放入a, 1 ∗ 3 1*3 13放入b, 1 ∗ 5 1*5 15放入c。然后开始生成第二个丑数:此时a、b、c三个队列队首元素最小的为a队首2,所以弹出2放入丑数数组v。同时,将 2 ∗ 2 2*2 22 2 ∗ 3 2*3 23 2 ∗ 5 2*5 25加入丑数队列。然后开始第3个丑数生成:此时a中元素为4,b中为3,6,c中为5,10,所以弹出3放入丑数数组中。依此类推。

ps:
尽管很简单,但写完了我的第一个CSDN博客还是有点小兴奋哈哈

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值