《剑指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\n");
    else
        printf("solution1 failed\n");

    if (GetUglyNumber_Solution2(index) == expected)
        printf("solution2 passed\n");
    else
        printf("solution2 failed\n");
}

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;
    }
};
牛客网提交代码

 

posted @ 2020-04-05 16:57  源周率  阅读(179)  评论(0编辑  收藏  举报