剑指offer:面试题49 丑数

剑指offer

面试题49

我们把只包含因子 2、3 和 5 的数称作丑数(Ugly Number)。求按从小到大的顺序的第 n 个丑数。

我的思路跟快速素数筛差不多。
这个题主要是去重很浪费时间,用map,set之类的容器去重会超时。

  • 1、弄明白快速素数筛的原理
  • 2、把快速数筛的思想用到这道题目
  • 3、这道题存在动态规划思想的解法

这道题用到的素数筛是因为,素数筛是筛选出素数的倍数,这道题是筛选出2,3,5的倍数,而且同一个数只能被筛一次。

丑数集合中每个数从小到大排列,每个丑数都是素数集合(2,3,5)中的数的乘积,第N个“丑数”就是在能由素数集合中的数相乘得来的(包括它本身)第N小的数。
为了保证每一个数都只能被筛一次,我们采用的方法是

// v = [2,3,5]
if(f % v[i] == 0) break;

当前的丑数 f * v[i] 也是一个丑数,如果 f % v[i] == 0,那么
f * v[i+1]=k*v[i]*v[i+1]=ff*v[i],保证每一个丑数都只能被因数中最小的素数筛掉,这样就能避免重复筛选。

int nthUglyNumber(int n)
{
    if(n == 1) return 1;
    priority_queue <long long, vector<long long>, greater<long long> > q;
    vector<long long> v;
    v.clear();
    q.push(1);
    v.push_back(2);
    v.push_back(3);
    v.push_back(5);
    int ans ;
    for(int i=0; i<n; i++)
    {
        int f = q.top();
        q.pop();
        v.push_back(f);
        for(int i=0; i<3; i++)
        {
            q.push(v[i] * f);
            if(f % v[i] == 0) break;
        }
    }
    return v[v.size()-1] ;
}

你可能感兴趣的:(剑指offer,数论)