丑数(队列的运用)

题目描述

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

分析

首先从丑数的定义是一个丑数的因子只有2,3,5,那么丑数p = 2 ^ x * 3 ^ y * 5 ^ z,换句话说一个丑数一定由另一个丑数乘以2或者乘以3或者乘以5得到,那么我们从1开始乘以2,3,5,就得到2,3,5三个丑数,然后依次乘以相同的倍数,然后取最小的数加入丑数数组。因此我们可以建立三个队列:
(1)丑数数组: 1
乘以2的队列:2
乘以3的队列:3
乘以5的队列:5
选择三个队列头最小的数2加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(2)丑数数组:1,2
乘以2的队列:4
乘以3的队列:3,6
乘以5的队列:5,10
选择三个队列头最小的数3加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(3)丑数数组:1,2,3
乘以2的队列:4,6
乘以3的队列:6,9
乘以5的队列:5,10,15
选择三个队列头里最小的数4加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(4)丑数数组:1,2,3,4
乘以2的队列:6,8
乘以3的队列:6,9,12
乘以5的队列:5,10,15,20
选择三个队列头里最小的数5加入丑数数组,同时将该最小的数乘以2,3,5放入三个队列;

(5)丑数数组:1,2,3,4,5
乘以2的队列:6,8,10,
乘以3的队列:6,9,12,15
乘以5的队列:10,15,20,25
选择三个队列头里最小的数6加入丑数数组,但我们发现,有两个队列头都为6,所以我们弹出两个队列头,同时将12,18,30放入三个队列;

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        // 0-6的丑数分别为0-6
        if(index < 7) return index;
        //p2,p3,p5分别为三个队列的指针,newNum为从队列头选出来的最小数
        int p2 = 0, p3 = 0, p5 = 0, newNum = 1;
        vector<int> arr;
        arr.push_back(newNum);
        while(arr.size() < index) {
            //选出三个队列头最小的数
            newNum = min(arr[p2] * 2, min(arr[p3] * 3, arr[p5] * 5));
            //这三个if有可能进入一个或者多个,进入多个是三个队列头最小的数有多个的情况
            if(arr[p2] * 2 == newNum) p2++;
            if(arr[p3] * 3 == newNum) p3++;
            if(arr[p5] * 5 == newNum) p5++;
            arr.push_back(newNum);
        }
        return newNum;
    }
};
队列在消息队列方面的运用非常广泛,它是一种常见的数据结构,用于实现消息的异步传输和处理。消息队列是一种基于生产者-消费者模型的通信机制,通过将消息发送到队列中,实现了解耦和异步处理的目的。 在消息队列中,队列被用作存储消息的容器。生产者将消息发送到队列的末尾,而消费者则从队列的头部获取消息进行处理。这种方式可以实现生产者和消费者之间的解耦,使得它们可以独立地进行工作。 消息队列在分布式系统中有着广泛的应用,它可以用于以下方面: 1. 异步任务处理:生产者将任务发送到队列中,消费者从队列中获取任务并进行处理。这样可以实现任务的异步执行,提高系统的吞吐量和响应速度。 2. 应用解耦:不同的应用之间可以通过消息队列进行通信,将消息发送到队列中,其他应用可以从队列中获取消息并进行相应的处理。这样可以实现应用之间的解耦,提高系统的可扩展性和灵活性。 3. 流量削峰:当系统面临高并发请求时,可以将请求发送到消息队列中进行缓冲,然后由消费者按照自己的处理能力进行处理。这样可以平滑处理高峰期的请求,避免系统的过载。 4. 日志收集:将系统的日志信息发送到消息队列中,然后由消费者进行处理和存储。这样可以实现日志的集中管理和分析,方便故障排查和系统优化。 总之,队列在消息队列方面的运用可以提供异步处理、解耦、流量控制和日志收集等功能,为分布式系统的设计和实现提供了很大的便利性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值