剑指offer 34---丑数

来源:互联网 发布:js怎么控制class 编辑:程序博客网 时间:2024/05/18 16:55

题目:

求按从小到大的第1500个丑数。

丑数:

只包含因子2,3,5的数称为丑数。所谓一个数m是另一个数n的因子,是指n能被m整除。

例:

   

解1:直观解法,从1开始计算,然后计数,直到第1500个丑数

缺陷:每个整数都需要计算,效率非常低

//判断是不是丑数bool IsUflyNum(int num){if (num <= 0){return false;}while (num % 2 == 0)    {num = num / 2;}while (num % 3 == 0){num = num / 3;}while (num % 5 == 0){num = num / 5;}//要求不能有除了2,3,5之外的因子return (num == 1) ? true: false;}int GetNum(int n)    //此处n代表第n个丑数{if (n <= 0){return 0;}int count = 0;int i = 1;while (1){if (count <= n){if (IsUflyNum(i) == 1)    //说明此时的i为丑数{count++;}}if (count == n){return i;}++i;}}

void TestUglyNum(){int tty = GetNum(1500);cout << tty << endl;}

解2:用空间换时间

缺陷:需要额外开辟空间来存储丑数


int Min(int num2, int num3, int num5)    //返回三个数中的最小的{int temp = (num2 < num3) ? num2 : num3;    //先找出num2,num3中的最小值return (temp < num5) ? temp : num5;}int GetUglyNum(int n)      //此处n代表为第n个丑数{if (n <= 0){return 0;}int* temp = new int[n];    //开辟一个大小为n的数组存放排序的丑数assert(temp);   //判断数组空间是否开辟成功for (int i = 0; i < n; ++i){temp[i] = 0;}int* ptr2 = temp;int* ptr3 = temp;int* ptr5 = temp;temp[0] = 1;   //第一个丑数为1,不用计算int index = 1;    //当前数组下标while (index < n){//比较三个指针指向位置的值分别乘以2,3,5,取最小值存储int min = Min((*ptr2) * 2, (*ptr3) * 3, (*ptr5) * 5);     //此时找到三个数里面的最小值temp[index] = min;index++;while (min >= (*ptr2) * 2){++ptr2;}while (min >= (*ptr3) * 3){++ptr3;}while (min >= (*ptr5) * 5){++ptr5;}}int tty = temp[n - 1];delete[] temp;return tty;}

void TestUglyNum(){int tty = GetUglyNum(1500);cout << tty << endl;}