题目描述:
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。

分析:只能被2、3、5整除是指如果一个数能被2整除,则一直除以2,得到的结果为1。

思路1:直观的从小到大对每个数进行判断,直到找到第N个丑数位置。但是时间复杂度太高,会超时

class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<1)
return -1;
int count=0;
int i=1;
while(i){
if(isUgly(i))
count++;
if(count==index)
break;
i++;
}
return i;
}
bool isUgly(int n){
while(n%2==0)
n/=2;
while(n%3==0)
n/=3;
while(n%5==0)
n/=5;
return (n==1)?true:false;
}
};

思路2:在已经获得前面丑数的基础上获得后面的丑数,减少了很多没用的计算。题目要求获得第N个丑数,按照从小到大的顺序排列,则后面的丑数一定能够通过前面的丑数*2,*3,5得到,所以需要遍历前面已经得到的排好序的丑数,分别对应2,*3,5,找到第一个比当前最大丑数大一点的新丑数,这个新丑数一定是通过前面某一个丑数2,*3,*5得到的,所以只需要比较这三种得到方式得到的丑数,即可得到下一个丑数。

class Solution {
public:
int GetUglyNumber_Solution(int index) {
if(index<1)
return 0;
int *pUgly=new int[index];
pUgly[0]=1;
int nextUgly=1;
int *multi2=pUgly;
int *multi3=pUgly;
int *multi5=pUgly;
while(nextUgly<index){
int min=Min(*multi2*2,*multi3*3,*multi5*5);
pUgly[nextUgly]=min;
while(*multi2*2<=pUgly[nextUgly])
++multi2;
while(*multi3*3<=pUgly[nextUgly])
++multi3;
while(*multi5*5<=pUgly[nextUgly])
++multi5;
nextUgly++;
}
int ugly=pUgly[nextUgly-1];
delete[] pUgly;
return ugly;
}
int Min(int number1,int number2,int number3){
int min_=min(number1,min(number2,number3));
return min_;
}
};