题目描述
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
时间限制:1秒 空间限制:32768K 热度指数:209207
本题知识点: 数组
思路
1.穷举(超时)
class Solution {
public:
int GetUglyNumber_Solution(int n) {
if(n==1)
return 1;
int count=1;
int t=2;
while(count!=n)
{
if(IsUgly(t++))
++count;
}
return --t;
}
bool IsUgly(int n)
{//将某个数中的质因子2,3,5除尽,若不为1,则不是丑数
while(n%2==0)
{
n=n/2;
}
while(n%3==0)
{
n=n/3;
}
while(n%5==0)
{
n=n/5;
}
if(n!=1)
return false;
else return true;
}
};
2.(学习牛客网评论代码)
- 即从丑数定义可知 ,任何一个丑数= 2 ^n + 3 ^m + 5 ^ k(其中m,n,k为自然数)
- 那么从1出发,对1 乘2,3,5 得2,3,5,再对2,3,5做如上乘法,可得其余丑数
- 为维护数组递增性,可以用三个标记p2,p3,p5表示丑数数组已乘过2,3,5的数的下标值
即最开始时,p2=p3=p5=0(数组下标从0开始),且丑数数组a[0]=1,最后每次取min(a[p2]*2,a[p3]3,a[p5]5)为下一个丑数,并将相应下标+1,这样可保证数组递增性(为避免重复,如6=23=32,此时应将两个下标同时+1,表示此位置已乘过2,3)
class Solution {
public:
int GetUglyNumber_Solution(int n) {
//1-6为前6个丑数
if(n<=6)
return n;
vector<int> a;
a.push_back(1);
int p2=0,p3=0,p5=0;
for(int i=1;i<n;++i)
{
a.push_back(min(a[p2]*2,min(a[p3]*3,a[p5]*5)));
if(a[i]==a[p2]*2)//不用else if是为了防止重复值
{
++p2;
}
if (a[i]==a[p3]*3)
{
++p3;
}
if (a[i]==a[p5]*5)
{
++p5;
}
}
return a[n-1];
}
};