zoukankan      html  css  js  c++  java
  • 20 丑数

    0 引言

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

    1 抽象问题具体化

    举例:求按从小到大的第8个丑数。

      解法1:列举法:1,2,3,4,5,6,8,9.

      解法2:利用原理 丑数必为另一个丑数与2/3/5相乘之积

    2 具体问题抽象分析

    (1)第一种解法算法描述

      1. 进入循环,for 1: 不知道啥时候

      2. 对每一个数进行判断,如果某个数满足丑数的定义,则count ++;

      3. 直到count == index,停止循环,输出结果.

    (2)第二种解法算法描述  

       1. 构建丑数数组,从小到大排列

       2. 利用1中的数组,寻找下一个丑数,加入到数组中

       3. 直到数组的size达到index为止 

    3 demo

    bool isUglyNumber(int num){
        while(num %2 == 0)
            num /= 2;
        while(num %3 == 0)
            num /= 3;
        while(num %5 == 0)
            num /= 5;
        return (n == 1)? true : false;
    }
    int GetUglyNumber_Solution(int index) {
        if(index < 1)
            return 0;
        int count = 0;
        for(int i=1;;i++){
            if(isUglyNumber(i))
                ++ count;
            if(count == index)
                return i;
        }        
    } 

    该解法的时间复杂度非常高,遍历次数取决于该丑数有多大,在实际应用中算得很慢。

    4 代码优化 

    int GetUglyNumber_Solution(int index) {
        if(index < 1)
            return 0;
        vector<int> uglyNums;
        uglyNums.push_back(1);
        int t2 =0, t3=0, t5 =0;
    for(int i=0;i<index;i++){
            // *2
            int m2 =1, m3=1,m5=1;
            for(int j = t2; j<uglyNums.size(); j++){
                m2 = uglyNums[j] * 2;
                if(m2 > uglyNums[uglyNums.size()-1]){
                    t2 = j;
                    break;
                }                    
            }
            // *3
            for(int j = t3; j<uglyNums.size(); j++){
                m3 = uglyNums[j] * 3;
                if(m3 > uglyNums[uglyNums.size()-1]){
                    t3 = j;
                    break;
                }                    
            }
            // *5
            for(int j = t5; j<uglyNums.size(); j++){
                m5 = uglyNums[j] * 5;
                if(m5 > uglyNums[uglyNums.size()-1]){
                    t5 = j;
                    break;
                }                    
            }
            uglyNums.push_back(min(min(m2,m3),m5));
        }
        return uglyNums[index-1];
    }

    实际测试,快了不止一星半点。以计算第10000个丑数为例,3中的方法要循环 288325195312500000次,而4中的方法只需要循环5000次即可。

  • 相关阅读:
    android学习笔记(一)
    中缀表达式转后缀表达式
    evernote使用推荐
    guns框架初试(一)eclipse环境配置之lombok
    guns框架初试(三)eclipse环境配置之成功运行
    guns框架初试(二)环境配置之数据库配置以及被迫修改数据库密码
    ssh 连接出错
    linux网银
    vimrepress
    gnome3自启动
  • 原文地址:https://www.cnblogs.com/ghjnwk/p/10126016.html
Copyright © 2011-2022 走看看