丑数35

题目描述:我们把只包含因子2、3和5的数称作丑数(UglyNumber)。求按从小到大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它含因子7。习惯上我们把1当作第一个丑数。
测试用例:

int main(){
    //要求的第n个丑数
    int n = 1500;
    //第n个丑数为
    int result = UglyNumber(n);
    //输出结果
    std::cout << "The N ugly number is: " << result;  //Output: 859963392

    return 0;
}

解题思路:

  1. 解法一:对每个数都计算是否为丑数,时间复杂度高,空间消耗少。
    a.使用一个函数判断是否为丑数
    b.在主函数中对每个数求是否为丑数,并计次。返回要求的第n个丑数。
    函数实现:
//判断数字是否为丑数
bool IsUgly(int number){
    while(number % 2 == 0)
        number /= 2;
    while(number % 3 == 0)
        number /= 3;
    while(number % 5 == 0)
        number /= 5;
    return (number == 1) ? true : false;
}
//解法一主函数
int UglyNumber(int index){
    if(index <= 0)
        return 0;
    //数字
    int number = 0;
    //计次
    int uglyTimes = 0;
    while(uglyTimes < index){
        ++number;
        if(IsUgly(number))
            uglyTimes++;
    }
    return number;
}
  1. 解法二:使用数组空间,只计算为丑数的数字。时间复杂度低,空间消耗多。
  2. 根据丑数的定义,丑数应该是另一个丑数乘以2、3或5得到的数
  3. 因此我们可以创建一个数组,里面的数字是排好序的丑数,每一个丑数都是前面的丑数乘以2、3或者5得到的。
  4. 如何确保数组里面的丑数是排好序的,对乘2、3或者5之后的丑数比较大小,小者为下一个丑数。
  5. 对乘以2而言,肯定存在某一个丑数T2,排在它之前的每一个丑数乘以2得到的结果都会小于已有最大的丑数,在它之后的每一个丑数乘以2得到的结果都会太大。我们只需记下这个丑数的位置,同时每次生成新的丑数的时候,去更新这个T2。对于乘以3和5而言,也存在着同样的T3和T5。

函数实现:

//解法二:效率高,空间消耗多
//三者去最小者
int Min(int n2, int n3, int n5){
    if(n2 < n3)
        return n2 < n5 ? n2 : n5;
    else
        return n3 < n5 ? n3 : n5;
}
int UglyNumber2(int index){
    if(index <= 0)
        return 0;
    //存放丑数的数组
    int *pUglyNumbers = new int[index];  //分配index的容量
    //第一个丑数为1
    pUglyNumbers[0] = 1;
    //下一个丑数下标,即第二个
    int nextUglyIndex = 1;
    //保存乘2、3或5数组
    int *pMultiply2 = pUglyNumbers;
    int *pMultiply3 = pUglyNumbers;
    int *pMultiply5 = pUglyNumbers;
    while(nextUglyIndex < index){  //当未达到要求的第index个丑数时循环
        //当前丑数的最小者
        int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
        //将最小者赋值给丑数数组序列的下一个下标位置
        pUglyNumbers[nextUglyIndex] = min;
        //然后检查是否改变位置
        while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply2;//因为2、3、5初始化的时候是pUglyNumbers, 所以更新位置时会不断追踪下一个丑数位置
        while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply3;
        while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])
            ++pMultiply5;
        ++nextUglyIndex;   
    }
    int ugly = pUglyNumbers[nextUglyIndex - 1];
    delete[] pUglyNumbers;
    return ugly;
}
数字游戏 鼠[冲 马] 06,18,30,42 牛[冲 羊] 05,17,29,41 虎[冲 猴] 04,16,28,40 兔[冲 鸡] 03,15,27,39 龙[冲 狗] 02,14,26,38 蛇[冲 猪] 01,13,25,37,49 马[冲 鼠] 12,24,36,48 羊[冲 牛] 11,23,35,47 猴[冲 虎] 10,22,34,46 鸡[冲 兔] 09,21,33,45 狗[冲 龙] 08,20,32,44 猪[冲 蛇] 07,19,31,43 五行对照,金木水火土的顺序, 金 03,04,11,12,25,26,33,34,41,42 木 07,08,15,16,23,24,37,38,45,46 水 13,14,21,22,29,30,43,44 火 01,02,09,10,17,18,31,32,39,40,47,48 土 05,06,19,20,27,28,35,36,49 波色 红波 01,02,07,08,12,13,18,19,23,24,29,30,34,35,40,45,46 蓝波 03,04,09,10,14,15,20,25,26,31,36,37,41,42,47,48 绿波 05,06,11,16,17,21,22,27,28,32,33,38,39,43,44,49 合数单双 合数单 01,03,05,07,09,10,12,14,16,18,21,23,25,27,29,30,32,34,36,38,41,43,45,47,49 合数双 02,04,06,08,11,13,15,17,19,20,22,24,26,28,31,33,35,37,39,40,42,44,46,48 生肖属性 家禽:牛、马、羊、鸡、狗、猪 野兽:鼠、虎、兔、龙、蛇、猴 吉美:兔、龙、蛇、马、羊、鸡 凶丑:鼠、牛、虎、猴、狗、猪 阴性:鼠、龙、蛇、马、狗、猪 阳性:牛、虎、兔、羊、猴、鸡 单笔:鼠、龙、马、蛇、鸡、猪 双笔:虎、猴、狗、兔、羊、牛 天肖:兔、马、猴、猪、牛、龙 地肖:蛇、羊、鸡、狗、鼠、虎 白边:鼠、牛、虎、鸡、狗、猪 黑中:兔、龙、蛇、马、羊、猴 女肖:兔、蛇、羊、鸡、猪 男肖:鼠、牛、虎、龙、马、猴、狗 三合:鼠龙猴、牛蛇鸡、虎马狗、兔羊猪 六合:鼠牛、龙鸡、虎猪、蛇猴、兔狗、马羊 新六合:鼠马,牛羊,虎猴,兔鸡,龙狗,蛇猪 琴:兔蛇鸡 棋:鼠牛狗 书:虎龙马 画:羊猴猪 五福肖:鼠、虎、兔、蛇、猴 红肖:马、兔、鼠、鸡 蓝肖:蛇、虎、猪、猴 绿肖:羊、龙、牛、狗 按照以上数字,和生肖 分别是 第一个13蛇水 第二个25蛇金 第三个22猴水 第四个39兔火 第五个48马火 第六个23羊木 第七个21鸡水 第八个29牛水 第九个25蛇金 第十个20狗土 第十一个40虎火 第十二个20狗土 第十三个28虎土 第十四个42鼠金 第十五个37蛇木 第十六个07猪木 第十七个30鼠水 第十八个12马金 第十九个12马金 第二十个18鼠火 第二十一个43猪水 第二十二个05牛土 第二十三个49蛇土 第二十四个10猴火 第二十五个11羊金 第二十六个25蛇金 第二十七个44狗水 第二十八个42鼠金 第二十九个20狗土 第三十个31猪火 第三十一个24马木 第三十二个11羊金 第三十三个10猴火 第三十四个35羊土 第三十五个23羊木 第三十六个31猪火 第三十七个48马火 第三十八个12马金 第三十九个44狗水 第十四个44狗水 第四十一个29牛水 第四十二个43猪水 第四十三个49蛇土 第四十四个40虎火 第四十五个03兔金 第四十六个35羊土 第四十七个09鸡火 第四十八个22猴水 根据第一到第四十八的规律,第四十九个是什么?要三个数字是什么?要五个数字是什么?要七个数字是什么?要九个数字是什么?要十一个数字是什么?要十三个数字是什么?一共七个请分别回答。
最新发布
03-20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值