丑数(空间换时间)

根据丑数的定义, 丑数应该是另一个丑数乘以 2、3 或者 5 的结果(1 除外)。因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以 2、3 或者 5 得到的。

这种思路的关键在于怎样确保数组里面的丑数是排好序的。假设数组中已经有若干个丑数排好序后存放在数组中,并且把己有最大的丑数记做M,我们接下来分析如何生成下一个丑数。该丑数肯定是前面某一个丑数乘以 2、3 或者 5 的结果, 所以我们首先考虑把已有的每个丑数乘以 2。在乘以 2 的时钝能得到若干个小于或等于 M 的结果。由于是按照顺序生成的,小于或者等于 M 肯定己经在数组中了,我们不需再次考虑:还会得到若干个大于 M 的结果,但我们只需要第一个大于 M 的结果,因为我们希望丑数是按从小到大的顺序生成的,其他更大的结果以后再说。我们把得到的第一个乘以 2 后大于 M 的结果记为 M2,同样,我们把已有的每一个丑数乘以 3 和 5,能得到第一个大于 M 的结果 M3 和 M,那么下一个丑数应该是 M2、M3 和 M5 这 3 个数的最小者。

前面分析的时候,提到把已有的每个丑数分别都乘以 2、3 和 5。事实上这不是必须的,因为已有的丑数是按顺序存放在数组中的。对乘以 2 而言, 肯定存在某一个丑数 T2,排在它之前的每一个丑数乘以 2 得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以 2 得到的结果都会太大。我们只需记下这个丑数的位置, 同时每次生成新的丑数的时候,去更新这个 T2。对乘以 3 和 5 而言, 也存在着同样的 T3 和 T5。

class Solution {
public:
    int GetUglyNumber_Solution(int index) {
        if(index<7)
            return index;
        vector<int> ugly(index);
        for(int i = 0;i<6;++i)
            ugly[i]=i+1;
        
        int t2=3,t3=2,t5=1;
        for(int i=6;i<index;++i)
        {
            //取t2,t3,t5最小的那个
            ugly[i]  = min(ugly[t2] * 2, min(ugly[t3] * 3, ugly[t5] * 5));
            //更新t2,t3,t5
            while(ugly[t2]*2<=ugly[i]) t2++;
            while(ugly[t3]*3<=ugly[i]) t3++;
            while(ugly[t5]*5<=ugly[i]) t5++;
        }
        return ugly[index-1];
    }
};
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 题目49:丑数 我们把只包含因子2、3 和5 的数称作丑数(Ugly Number)。求从小到大的顺序的第1500...
    stoneyang94阅读 674评论 0 0
  • 题目:丑数 我们把只包含因子2,3,5的数称为丑数(Ugly Number). 求按从小到大的顺序的第1500个丑...
    Ferrari1001阅读 1,175评论 0 0
  • 题目描述 把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包...
    丶沧月阅读 286评论 0 0
  • 第5章 引用类型(返回首页) 本章内容 使用对象 创建并操作数组 理解基本的JavaScript类型 使用基本类型...
    大学一百阅读 3,692评论 0 4
  • 人自从出生的那刻起就踏上了追求理想的道路,每一个人都有自己有独立的思想,每个人的追求目标也不一样,唯一相同...
    仄言101阅读 413评论 0 1

友情链接更多精彩内容