题:把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路一:
一个个数试探:对任一数,若能被2整除,连续除以2;若能被3整除,连续除以3;若能被5整除,连续除以5,最后得到的数为1,说明时丑数,不然不是。然后将该数加1继续判断,直到找到第N个丑数。
思路二:
思路一,是对每个数都判断了,这样花费时间,我们可以创建一个数组,里面的数字都是排好的丑数,每一个丑数都是前面的丑数乘以2、3或5得到的。但是关键的是如何保证大小顺序?如{1}乘以以后得到{1,2,3,5}这时再从2开始乘,得到{1,2,3,5,4,6,10},我们发现这个不是从大小顺序了,也就是不能之间按顺序乘完以后排在后面就行。我们可以,定义三个指针(分别对应着乘以2、3、5)都指向开始,将三个指针指向的数乘以对应的数(2、3、5),将其结果中的最小值放入数列中,然后找到最小数对应的指针将其前移一位;再将三个指针指向的数乘以对应的数(2、3、5)取最小值加入数列,依次下去,直到找到第N个丑数。代码如下:
1 class Solution { 2 public: 3 int GetUglyNumber_Solution(int index) 4 { 5 if(index<=0) return 0; 6 7 int *pUgly=new int[index]; 8 pUgly[0]=1; 9 int i=1; 10 11 int *pMulti2=pUgly; 12 int *pMulti3=pUgly; 13 int *pMulti5=pUgly; 14 15 while(i<index) 16 { 17 int minVal=Min(*pMulti2*2,*pMulti3*3,*pMulti5*5); 18 pUgly[i]=minVal; 19 20 //找最小值对应的下标,移动一位 21 while(*pMulti2*2<=pUgly[i]) 22 { 23 ++pMulti2; 24 } 25 while(*pMulti3*3<=pUgly[i]) 26 { 27 ++pMulti3; 28 } 29 while(*pMulti5*5<=pUgly[i]) 30 { 31 ++pMulti5; 32 } 33 ++i; 34 } 35 int ugly=pUgly[i-1]; 36 delete[] pUgly; 37 return ugly; 38 } 39 40 int Min(int number1,int number2,int number3) 41 { 42 int min=(number1<number2)?number1:number2; 43 min=(min<number3)?min:number3; 44 45 return min; 46 } 47 };
注意的是:三个指针除开始外,不是同时指向一个数。