264. Ugly Number II

来源:互联网 发布:ps制作淘宝店铺招牌 编辑:程序博客网 时间:2024/04/29 02:29

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

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

Note that 1 is typically treated as an ugly number.

Hint:

  1. The naive approach is to call isUgly for every number until you reach the nth one. Most numbers are not ugly. Try to focus your effort on generating only the ugly ones.
  2. An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
  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.
  4. Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).

解答:

用三个数分别充当2,3,5的指针,开始指向数组的0号位置,该位置先存入1.当这三个指针所指的数乘以各自的值(2,3,5)的结果进行比较,选取最小的那个加入数组中,同时该指针加一。

这里有个小tip: 

2*3 和3*2重复,因此我的代码里是判断当前值是否与数组末尾的值相同,若相同就不加入数组。但不管相不相同,指针都加一,相同加一说明当前值跳过。

别人的代码里是进行顺序判断,若两个当前结果都一样,则都会进行指针加一,比我的效率高。

以下是代码:

1.我的代码 36ms

class Solution {public:    int nthUglyNumber(int n) {        vector<int>res;        int index = 1;        res.push_back(1);        int two = 0,  three = 0, five = 0;        while(index < n){            int t1 = res[two]*2;            int t2 = res[three]*3;            int t3 = res[five]*5;            int minn = 0;            if(t1 <= t2){                if(t1 <= t3){                    minn = t1;                    ++two;                }else{                    minn = t3;                    ++five;                }            }else{                if(t2 <= t3){                minn = t2;                ++three;                }                else{                minn = t3;                ++five;                }            }            if(minn != res.back()){                res.push_back(minn);                index++;            }        }        return res.back();    }};

2.别人的代码 16 ms (差距啊~~~

We have an array k of first n ugly number. We only know, at the beginning, the first one, which is 1. Then

k[1] = min( k[0]x2, k[0]x3, k[0]x5). The answer is k[0]x2. So we move 2's pointer to 1. Then we test:

k[2] = min( k[1]x2, k[0]x3, k[0]x5). And so on. Be careful about the cases such as 6, in which we need to forward both pointers of 2 and 3.

x here is multiplication.

class Solution {public:    int nthUglyNumber(int n) {        if(n <= 0) return false; // get rid of corner cases         if(n == 1) return true; // base case        int t2 = 0, t3 = 0, t5 = 0; //pointers for 2, 3, 5        vector<int> k(n);        k[0] = 1;        for(int i  = 1; i < n ; i ++)        {            k[i] = min(k[t2]*2,min(k[t3]*3,k[t5]*5));            if(k[i] == k[t2]*2) t2++;             if(k[i] == k[t3]*3) t3++;            if(k[i] == k[t5]*5) t5++;        }        return k[n-1];    }};


0 0
原创粉丝点击