zoukankan      html  css  js  c++  java
  • 《剑指offer》第四十九题:丑数

    // 面试题49:丑数
    // 题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到
    // 大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。
    // 习惯上我们把1当做第一个丑数。
    
    #include <cstdio>
    
    // ====================算法1的代码====================
    // 蛮力法, 时间复杂度较高
    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 GetUglyNumber_Solution1(int index)
    {
        if (index <= 0)
            return 0;
    
        int number = 0;
        int uglyNumber = 0;
        while (uglyNumber < index)
        {
            ++number;
    
            if (IsUgly(number))
                ++ uglyNumber;
        }
        return number;
    }
    
    // ====================算法2的代码====================
    // 按顺序求解下一位丑数, 需要占用额外的空间消耗
    int Min(int number1, int number2, int number3);
    
    int GetUglyNumber_Solution2(int index)
    {
        if (index <= 0)
            return 0;
    
        int* pUglyNumbers = new int[index];
        pUglyNumbers[0] = 1;  //第一位丑数为1
        int nextUglyIndex = 1;  //找到的丑数
    
        int* pMultiply2 = pUglyNumbers;  //乘以2的丑数索引. 乘以2刚好大于当前最大丑数
        int* pMultiply3 = pUglyNumbers;  //乘以2的丑数索引.
        int* pMultiply5 = pUglyNumbers;  //乘以5的丑数索引.
    
        while (nextUglyIndex < index)
        {
            int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);  //保存当前索引的最小值
            pUglyNumbers[nextUglyIndex] = min;
    
            while (*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex])  //更新当前索引, 使其乘以2刚好大于当前最大丑数
                ++pMultiply2;
            while (*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex])  //更新当前索引
                ++pMultiply3;
            while (*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex])  //更新当前索引
                ++pMultiply5;
    
            ++nextUglyIndex;
        }
        int ugly = pUglyNumbers[nextUglyIndex - 1];  //第index位等于数组索引中index-1
        delete[] pUglyNumbers; //记得删除掉创建的数组
        return ugly;
    }
    
    int Min(int number1, int number2, int number3)
    {
        int min = (number1 < number2) ? number1 : number2;
        min = (min < number3) ? min : number3;
    
        return min;
    }
    // ====================测试代码====================
    void Test(int index, int expected)
    {
        if (GetUglyNumber_Solution1(index) == expected)
            printf("solution1 passed
    ");
        else
            printf("solution1 failed
    ");
    
        if (GetUglyNumber_Solution2(index) == expected)
            printf("solution2 passed
    ");
        else
            printf("solution2 failed
    ");
    }
    
    int main(int argc, char* argv[])
    {
        Test(1, 1);
    
        Test(2, 2);
        Test(3, 3);
        Test(4, 4);
        Test(5, 5);
        Test(6, 6);
        Test(7, 8);
        Test(8, 9);
        Test(9, 10);
        Test(10, 12);
        Test(11, 15);
    
        //Test(1500, 859963392);
    
        Test(0, 0);
    
        return 0;
    }
    测试代码

    分析:空间换时间。

    class Solution {
    public:
        int GetUglyNumber_Solution(int index) {
        
            if (index <= 0)
                return 0;
            
            int* pUglyNumbers = new int[index];
            pUglyNumbers[0] = 1;
            int nextUglyIndex = 1;
            
            int* pMultiply2 = pUglyNumbers;
            int* pMultiply3 = pUglyNumbers;
            int* pMultiply5 = pUglyNumbers;
            
            while (nextUglyIndex < index)
            {
                int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5);
                pUglyNumbers[nextUglyIndex] = min;
                
                while(*pMultiply2 * 2 <=  pUglyNumbers[nextUglyIndex])
                    ++pMultiply2;
                while(*pMultiply3 * 3 <=  pUglyNumbers[nextUglyIndex])
                    ++pMultiply3;
                while(*pMultiply5 * 5 <=  pUglyNumbers[nextUglyIndex])
                    ++pMultiply5;
                ++nextUglyIndex;
            }
            int ugly = pUglyNumbers[nextUglyIndex - 1];
            delete[] pUglyNumbers;
            return ugly;
        }
        
        int Min(int number1, int number2, int number3)
        {
            int min = (number1 < number2) ? number1 : number2;
            min = (min < number3) ? min : number3;
            
            return min;
        }
    };
    牛客网提交代码
  • 相关阅读:
    windows 安装mysql 步骤
    x-editable 的使用方法
    asp.net连接数据库
    fedora下根据字符查找软件包
    ubuntu 常用命令
    第8课-库函数方式文件编程
    第7课-系统调用方式文件编程
    第6课-函数库设计
    第5课-Linux编程规范
    第4课-Linux应用程序地址布局
  • 原文地址:https://www.cnblogs.com/ZSY-blog/p/12637920.html
Copyright © 2011-2022 走看看