// 面试题49:丑数 // 题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。求按从小到 // 大的顺序的第1500个丑数。例如6、8都是丑数,但14不是,因为它包含因子7。 // 习惯上我们把1当做第一个丑数。 #include <iostream> // ====================算法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 uglyFound = 0; while (uglyFound < index)//从头到尾开始计算 { ++number; if (IsUgly(number)) ++uglyFound; } 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; 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; } // ====================测试代码==================== 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); system("pause"); return 0; }