根据丑数定义,能写成2/3/5乘积的数即为丑数,按照此原理写下面代码,但是算法时间复杂度过高。 改进1:增加长度为1000的辅助数组,如果将数分解到1000以内的时候,直接判断是否是丑数,但是运行时间好像没啥变化,尝试失败。
/** *Copyright @ 2019 Zhang Peng. All Right Reserved. *Filename: *Author: Zhang Peng *Date: *Version: *Description:剑指offer 面试题49 丑数 **/ #include<iostream> #include<ctime> using namespace std; class Solution { private: const int maxlen = 10; public: bool isUglynum(int num, int * record) { int temp = num; /*if(record[temp]!=-1) return (bool)record[temp];*/ while (temp % 2 == 0) { temp /= 2; if (num <= maxlen&&record[temp] != -1) { record[num] = record[temp]; return (bool)record[temp]; } } while (temp % 3 == 0) { temp /= 3; if (num <= maxlen&&record[temp] != -1) { record[num] = record[temp]; return (bool)record[temp]; } } while (temp % 5 ==0) { temp /= 5; if (num <= maxlen&&record[temp] != -1) { record[num] = record[temp]; return (bool)record[temp]; } } bool result_final; if (temp == 1) { result_final = true; if (num <= maxlen) { record[num] = 1; } } else { result_final = false; if (num <= maxlen) { record[num] = 0; } } return result_final; } int GetUglyNumber_Solution(int index) { if (index <= 0) return 0; int i = 1; int * record=new int[maxlen]; for (int k = 0; k<maxlen; k++) record[k] = -1; record[1] = 1; if (index == 1) return 1; else { int count = 1; while (count != index) { i++; if (isUglynum(i, record)) { cout << i << " "; count++; } } } return i; } }; int main() { Solution s; clock_t start, finish; start = clock(); int num = s.GetUglyNumber_Solution(1500); cout << endl; cout << num << endl; finish = clock(); cout << "consume time: " << finish - start << "ms" << endl; system("pause"); return 0; }图中单位有误,应为ms 改进2:上述思路主要是需要判断每一个数是否是丑数,如果我们可以生成每一个丑数,则不用判断那么多次,别的博客中称这一思路为构造法。
/** *Copyright @ 2019 Zhang Peng. All Right Reserved. *Filename: *Author: Zhang Peng *Date: *Version: *Description:剑指offer 面试题49 丑数 **/ #include<iostream> #include<ctime> using namespace std; class Solution { public: int Min(int x1, int x2, int x3) { int temp = (x1<x2) ? x1 : x2; return (temp<x3) ? temp : x3; } int GetUglyNumber_Solution(int index) { if (index <= 0) return 0; int * result = new int[index]; result[0] = 1; int nextindex = 1; int * point2 = result; int * point3 = result; int * point5 = result; while (nextindex<index) { int minvalue = Min((*point2) * 2, (*point3) * 3, (*point5) * 5); result[nextindex] = minvalue; cout << result[nextindex] << " "; while ((*point2) * 2 <= result[nextindex]) point2++; while ((*point3) * 3 <= result[nextindex]) point3++; while ((*point5) * 5 <= result[nextindex]) point5++; nextindex++; } int result_final = result[nextindex - 1]; delete[] result; return result_final; } }; int main() { Solution s; clock_t start, finish; start = clock(); int num = s.GetUglyNumber_Solution(1500); cout << endl; cout << num << endl; finish = clock(); cout << "consume time: " << finish - start << "ms" << endl; system("pause"); return 0; }结果如图: 两者速度上相差几十倍,这就是算法的力量。
