题目描述
把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
方法
//找到第N个丑数
//方法1:存放num之前所有元素是否是丑数的flag
int GetUglyNumber_Solution(int index) {
if(index < 1)
{
return -1;
}
if(index == 1)
{
return 1;
}
vector<bool> ugly_flag;
bool ugly = false;
int num = 1;
int count = 1;
ugly_flag.push_back(false);
ugly_flag.push_back(true);
while(count != index)
{
num++;
if(num%2 == 0)
{
ugly = ugly_flag[num/2];
}
else if(num%3 == 0)
{
ugly = ugly_flag[num/3];
}
else if(num%5 == 0)
{
ugly = ugly_flag[num/5];
}
else
{
ugly = false;
}
ugly_flag.push_back(ugly);
if(ugly)
{
count++;
}
}
return num;
}
//方法2:递归
bool bUglyNumber(int num)
{
if(num == 1)
{
return true;
}
if(num%2 == 0)
{
return bUglyNumber(num/2);
}
else if(num%3 == 0)
{
return bUglyNumber(num/3);
}
else if(num%5 == 0)
{
return bUglyNumber(num/5);
}
else
{
return false;
}
}
int GetUglyNumber_Solution_2(int index) {
if(index < 1)
{
return -1;
}
int num = 0;
int count = 0;
while(count != index)
{
num++;
if(bUglyNumber(num))
{
count++;
}
}
return num;
}
//方法3:既省空间又省时间的方法
//丑数数组升序排列,且最后一个数为M
//找到第一个*2之后大于M丑数M2及其位置t2
//找到第一个*3之后大于M丑数M3及其位置t3
//找到第一个*5之后大于M丑数M5及其位置t5
//取min(M2,M3,M5)为下一个丑数
//得到丑数位置的索引+1。比如M2为最小值,那么t2++。
int GetUglyNumber_Solution_3(int index) {
if(index < 1)
{
return 0;
}
int num = 1;
int count = 1;
vector<int> ugly;
int t2=0;
int t3=0;
int t5=0;
ugly.push_back(1);
while(count != index)
{
num = min(ugly[t2]*2, ugly[t3]*3);
num = min(ugly[t5]*5, num);
ugly.push_back(num);
count++;
while(ugly[t2]*2 <= num)
{
t2++;
}
while(ugly[t3]*3 <= num)
{
t3++;
}
while(ugly[t5]*5 <= num)
{
t5++;
}
}
return num;
}