题目:我们把只包含因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,
但14不是,因为它包含因子7。习惯上我们把1当做是第一个丑数。
求按从小到大的顺序的第1500个丑数。
分析:这是一道在网络上广为流传的面试题,据说google曾经采用过这道题。
分析:假设数组ugly[N]中存放不断产生的丑数,初始只有一个丑数ugly[0]=1,由此出发,下一个丑数由因子2,3,5竞争产生,得到ugly[0]*2, ugly[0]*3, ugly[0]*5, 显然最小的那个数是新的丑数,所以第2个丑数为ugly[1]=2,开始新一轮的竞争,由于上一轮竞争中,因子2获胜,这时因子2应该乘以ugly[1]才显得公平,得到ugly[1]*2,ugly[0]*3,ugly[0]*5, 因子3获胜,ugly[2]=3,同理,下次竞争时因子3应该乘以ugly[1],即:ugly[1]*2, ugly[1]*3, ugly[0]*5, 因子5获胜,得到ugly[3]=5,重复这个过程,直到第n个丑数产生。总之:每次竞争中有一个(也可能是两个)因子胜出,下一次竞争中 胜出的因子就应该乘下一个数。
#include <iostream>
#include <cstring>
using namespace std;
int getmin(int num1,int num2,int num3)//获取3个数中最小的那个
{
if(num1<num2)
{
if(num1>num3)
return num3;
else return num1;
}
else
{
if(num2<num3)
return num2;
else return num3;
}
}
int findUgly(int n)
{
int *ugly=new int [n];
ugly[0]=1;
int index2=0;//因子2的乘数下标
int index3=0;//因子2的乘数下标
int index5=0;//因子2的乘数下标
int index=1;
while(index<n)
{
int val=getmin(ugly[index2]*2,ugly[index3]*3,ugly[index5]*5);
if(val==ugly[index2]*2)
index2++;//如果这次是2的积最小,则2的乘数在数组里面后移一位,下同
if(val==ugly[index3]*3)
index3++;
if(val==ugly[index5]*5)
index5++;
ugly[index++]=val;
}
int result=ugly[n-1];
delete[] ugly;
return result;
}
int main( int argc, char ** argv )
{
cout<<findUgly(1500);
return 0;
}