您的位置:首页 > 其它

AcWing 62 丑数

2019-03-13 21:15 239 查看

题目描述:

我们把只包含因子2、3和5的数称作丑数(Ugly Number)。

例如6、8都是丑数,但14不是,因为它包含因子7。

求第n个丑数的值。

样例

[code]输入:5

输出:5

注意:习惯上我们把1当做第一个丑数。

分析:

方法一:

打表备查,将每个已经判断的丑数保存进哈希表,如果某数能被2,3,5之一整除且商为丑数,则该数为丑数。该方法缺点是内存消耗太大,超过了限制。如果在判断丑数的函数里返回m[n/2]之类的,空间会超过限制,如果返回count函数,时间也会超过限制,所以仅限于几百个以内的丑数的判断

[code]class Solution {
public:
unordered_map<int,int> m;
int getUglyNumber(int n) {
int i,cnt = 0;
for(i = 1;i < 6;i++){
m[i] = 1;
cnt++;
if(cnt == n)    return i;
}
while(1){
if(judge(i))    m[i]++,cnt++;
if(cnt == n)    return i;
i++;
}
}
bool judge(int n){
if(n % 2 == 0)  return m[n / 2];
if(n % 3 == 0)  return m[n / 3];
if(n % 5 == 0)  return m[n / 5];
return false;
}
};

方法二:

三指针法。先说下用的较少的vector的定义。

如果不提前定义vector的元素个数,之后会每次容量倍增的方式来拓展空间。

我们知道,丑数除了1一定是2,3,5的倍数,那么2的n倍,3的n倍,5的n倍也就是丑数的全集了。第一个丑数为1,那么接下的丑数就是1的2,3倍,1的二倍加入后,指针应该后移移到2,2的2被小于1的五倍,所以3之后还是要放进4.可能描述比较模糊,具体过程参考代码即可,类似于三路归并排序,从2,3,5的倍数组成的三个序列中每次挑出新的最小元素加入。

分析下过程:

向量q中,初始为1,先加入2,i++,再加入3,j++,加入4,i++,加入5,k++,加入6,i++,j++。可以看到,当加入的数是几个因子的倍数时,对应的指针都会++。

[code]class Solution {
public:
int getUglyNumber(int n) {
vector<int> q(1,1);
int i = 0,j = 0,k = 0;
while(--n){
int t = min(q[i]*2,min(q[j]*3,q[k]*5));
q.push_back(t);
if(q[i] * 2 == t)   i++;
if(q[j] * 3 == t)   j++;
if(q[k] * 5 == t)   k++;
}
return q.back();
}
};

 

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: