[LeetCode] 264. Ugly Number II

来源:互联网 发布:淘宝实名认证在哪里看 编辑:程序博客网 时间:2024/04/30 04:58

264. Ugly Number II 

Write a program to find the n-th ugly number.

Ugly numbers are positive numbers whose prime factors only include2, 3, 5. For example,1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first10 ugly numbers.

Note that 1 is typically treated as an ugly number.

Hint:

Show Hint

  1. The naive approach is to callisUgly for every number until you reach the nth one. Most numbers arenot ugly. Try to focus your effort on generating only the ugly ones.Show More Hint
  2. An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.Show More Hint
  3. The key is how to maintain the order of the ugly numbers. Try a similar approach of merging from three sorted lists: L1, L2, and L3.Show More Hint
  4. Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).


找出丑数,即分解质因数为2or3or5的数字。提示可以明白,丑数不是很多,所以暴力求解显然NG。另外很重要的一点,后面的丑数都是由前面的丑数乘以2or3or5得出来的。由于最大测试数据可能超过int范围,所以用long比较合适。
  
  1. 动规思路。根据提示给出的方法,维护三个表,分别是当前最小丑数分别乘以2、3、5得到的结果,而下一个丑数就是当前三个表头元素中最小的一个(类似归并排序),递归下去,可得到结果,不考虑表的操作,时间复杂度为O(n)。用priority_queue、set、list、map都可以实现。这里用map实现,因为可以直接利用他的自动排序功能,可以省去维护三个表的步骤。但是效率确实不怎么样,500ms。
  
class Solution {public:    int nthUglyNumber(int n) {        map<long,int> mp;        map<long,int>::iterator it;        mp.insert(pair<long,int>(1,0));        int sum;        for(it=mp.begin(),sum=1;sum<n;sum++,it++){            mp.insert(pair<long,int>(it->first*2,0));            mp.insert(pair<long,int>(it->first*3,0));            mp.insert(pair<long,int>(it->first*5,0));        }        return it->first;    }};

  2. 还有一种比较特殊的方法,利用三重循环,每层分别乘以2、3、5,并推进vector保存,可保证没有重复且较快速的算完。但是不保证先后插入的大小顺序,因此无法定量确定nth的具体出现位置,只好算出一个很大范围内的结果(这里选取INT_MAX),然后排序,得到结果。理论上复杂度是O(nlogn),但是测试只用了300+ms,果然stl比较费时吗=-=。
class Solution {public:    int nthUglyNumber(int n) {        vector<int> ugly;        long a, b,c;        int m = INT_MAX;            for (a = 1; a<=m; a*=2)                for (b = a; b<=m; b *= 3)                    for (c = b; c<=m; c *= 5)                        ugly.push_back(c);        sort(ugly.begin(), ugly.end());        return ugly[n-1];    }};


看到其他人的runtime大都集中在10ms左右觉得很诧异,就算第一种方法用set或者queue等也只能300+ms,然后网上查了查好像也没看到其他思路完全不同的方法,不知道那些大神们是怎么做到这么快的?????????????



0 0