本题来自《剑指offer》 丑数
题目:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路:
两种思路:
第一种:丑数的定义是只包含质因子2,3,5.那么该数如果一直能被235整除直到为1,那么就是丑数,python代码实现。该代码直观明了,用时间换空间。由于用到了多重循环,而且每个数字都要被计算,时间花销较大。
第二种:用空间换时间.丑数应该是另一个丑数乘以2,3,5的结果。可以定一个一块空间,存储着已经排好序的丑数,然后在乘以2,3,5.这种思路的前提是丑数应该是排好序的。C++代码实现。
C++ Code:
class Solution { public: int GetUglyNumber_Solution(int index) { if (index<=0){ //boundary condition judgement return 0; } int *pUglyNumbers = new int[index]; //cache pUglyNumbers[0] = 1; //the first number is 1 int nextUglyIndex = 1; //the index start from 1 int *pMultiply2 = pUglyNumbers; int *pMultiply3 = pUglyNumbers; int *pMultiply5 = pUglyNumbers; while (nextUglyIndex<index){ int min = Min(*pMultiply2*2,*pMultiply3*3,*pMultiply5*5); //get the smallest of the three numbers to cache it 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]; //the last one in the cache is the result value delete[] pUglyNumbers; //delete the cache,relative to new return ugly; } int Min(int num1,int num2,int num3){ //the smallest of the three numbers int min = (num1<num2)?num1:num2; min = (min<num3)?min:num3; return min; } };
Python Code:
# -*- coding:utf-8 -*- class Solution: def GetUglyNumber_Solution(self, index): # write code here result = 0 if index >= 1: result = 1 #the theory is that the first ugly number is 1,and the count start from 1 for num in range(2,index+1): #loop from 2 to the last number if self.IsUgly(num): result += 1 #counter accumulation statistics return result def IsUgly(self,num): #this program is to detmine whether the single number is ugly while(num%2 == 0): #detmine that the number can be divisible by 2 num /= 2 while(num%5 == 0): #detmine that the number can be divisible by 5 num /= 5 while(num%3 == 0): #detmine that the number can be divisible by 3 num /= 3 if num == 1: #only when the result is 1,this number is ugly return True else: return False