题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第1500个丑数。
分析:这是一道在网络上广为流传的面试题,据说google曾经采用过这道题。
所谓一个数m是另一个数n的因子,是指n能被m整除,也就是n % m == 0。根据丑数的定义,丑数只能被2、3和5整除。也就是说如果一个数如果它能被2整除,我们把它连续除以2;如果能被3整除,就连续除以3;如果能被5整除,就除以连续5。如果最后我们得到的是1,那么这个数就是丑数,否则不是。
1 { 2 while(number % 2 == 0) 3 number /= 2; 4 while(number % 3 == 0) 5 number /= 3; 6 while(number % 5 == 0) 7 number /= 5; 8 9 return (number == 1) ? true : false; 10 } 11 12 int GetUglyNumber_Solution1(int index) 13 { 14 if(index <= 0) 15 return 0; 16 17 int number = 0; 18 int uglyFound = 0; 19 while(uglyFound < index) 20 { 21 ++number; 22 23 if(IsUgly(number)) 24 { 25 ++uglyFound; 26 } 27 } 28 29 return number; 30 }
方法二:用空间换时间,创建数组保存已找到的丑数
设置三个指针,开始都指向数组的第一个元素,三个指针分别负责*2,*3,*5。用乘后的结果中最小的那个数更新数组,并与数组中最大的那个丑数比较,如果乘后的结果小于数组中最大丑数,那么这个指针就可以++(因为小于结果中最大的丑数已经存在了)
1 int Min(int number1, int number2, int number3); 2 3 int GetUglyNumber_Solution2(int index) 4 { 5 if(index <= 0) 6 return 0; 7 8 int *pUglyNumbers = new int[index]; 9 pUglyNumbers[0] = 1; 10 int nextUglyIndex = 1; 11 12 int *pMultiply2 = pUglyNumbers; 13 int *pMultiply3 = pUglyNumbers; 14 int *pMultiply5 = pUglyNumbers; 15 16 while(nextUglyIndex < index) 17 { 18 int min = Min(*pMultiply2 * 2, *pMultiply3 * 3, *pMultiply5 * 5); 19 pUglyNumbers[nextUglyIndex] = min; 20 21 while(*pMultiply2 * 2 <= pUglyNumbers[nextUglyIndex]) 22 ++pMultiply2; 23 while(*pMultiply3 * 3 <= pUglyNumbers[nextUglyIndex]) 24 ++pMultiply3; 25 while(*pMultiply5 * 5 <= pUglyNumbers[nextUglyIndex]) 26 ++pMultiply5; 27 28 ++nextUglyIndex; 29 } 30 31 int ugly = pUglyNumbers[nextUglyIndex - 1]; 32 delete[] pUglyNumbers; 33 return ugly; 34 } 35 36 int Min(int number1, int number2, int number3) 37 { 38 int min = (number1 < number2) ? number1 : number2; 39 min = (min < number3) ? min : number3; 40 41 return min; 42 }