题目要求:把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
一种直观的思路为从1开始遍历所有的数,看每个数是不是丑数,是的话计数器加1,加到index为止。
bool ugly(int index)
{
if(index<1)
return false;
while(index%2==0)
index= index/2;
while(index%3==0)
index= index/3;
while(index%5==0)
index= index/5;
if(index==1 )
return true;
else
return false;
}
int GetUglyNumber_Solution(int index) {
int cnt=0;
int i=1;
while(cnt!=index)
{
if(ugly (i))
cnt++;
i++;
}
return --i;
}
但是这样做时间复杂度特别大,所以要考虑简化。
只包含2,3,5因子的数为丑数,反过来用2,3,5相乘得到的数即为丑数。
所以我们只需要用2,3,5来构建数字即可。用三个指针来代表2,3,5用了几次,每次取组合出来最小的即可。
注:1.不能用if else,因为比如6,2和3的指针都会加1,但是如果有else,那么2的指针加1,3的指针不加,下次还会是6,造成数据重复。
2.Min函数只能有2个参数,所以要用两次min函数来进行比较。
int GetUglyNumber_Solution(int index) {
if(index<1)
return 0;
vector<int> dp(index,0);
dp[0]=1;
int cnt2=0,cnt3=0,cnt5=0;
for(int i=1;i<index;++i)
{
dp[i]= (min(min(dp[cnt2]*2,dp[cnt3]*3),dp[cnt5]*5));
if(dp[i]==dp[cnt2]*2)
cnt2++;
if(dp[i]==dp[cnt3]*3)
cnt3++;
if(dp[i]==dp[cnt5]*5)
cnt5++;
}
return dp[index-1];
}