面试49:丑数
把只包含质因子2、3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但14不是,因为它包含质因子7。 习惯上我们把1当做是第一个丑数。求按从小到大的顺序的第N个丑数。
思路跟书上一样:
class Solution {
public:
int GetUglyNumber_Solution(int index) {
if (index <= 0)
return 0;
//因为丑数的前5个数是1,2,3,4,5,所以可直接返回
if (index > 0 && index <= 5)
return index;
vector<int> sequenceUgly = { 1,2,3,4,5 };
return getUglyNumber(sequenceUgly, index);
}
//递归获得有序丑数数组
int getUglyNumber(vector<int>& sequenceUgly, int index)
{
int uglySize = sequenceUgly.size();
//若丑数数列达到要求长度,停止递归,返回尾部值即为所求
if (uglySize == index)
return sequenceUgly[uglySize - 1];
//M是原丑数数列中最大的一个数
int M = sequenceUgly[uglySize - 1];
//M2s是丑数数列乘以2之后,第一个大于M的数,M3,M5同理
int M2 = getMax(sequenceUgly, 2, M);
int M3 = getMax(sequenceUgly, 3, M);
int M5 = getMax(sequenceUgly, 5, M);
//求出M2,M3,M5中最小的一个数
int minM = min(M2, M3);
if (minM > M5)
minM = M5;
sequenceUgly.push_back(minM);
//cout << "minM: " << minM << endl;
return getUglyNumber(sequenceUgly, index);
}
//丑数数列中的数乘以data(2/3/5)后,挑选出大于M的第一个数返回
int getMax(vector<int>& sequenceUgly, int data, int M)
{
vector<int> duplicateUgly(sequenceUgly);
for (int i = 0; i < duplicateUgly.size(); ++i)
{
duplicateUgly[i] = duplicateUgly[i] * data;
}
int j = 0;
while (j<duplicateUgly.size()&&duplicateUgly[j]<=M)
{
++j;
}
return duplicateUgly[j];
}
};这里没有用那种逐个判断每个整数是否是丑数的方法,但还是贴上判断整数n是否为丑数的代码:
bool isUgly(int n)
{
while (n % 2 == 0)
n = n / 2;
while (n % 3 == 0)
n = n / 3;
while (n % 5 == 0)
n = n / 5;
return (n == 1) ? true : false;
}