[LeetCode] 264. Ugly Number II 醜陋數之二

 

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

Ugly numbers are positive numbers whose prime factors only include 2, 3, 5git

Example:github

Input: n = 10
Output: 12
Explanation:  is the sequence of the first  ugly numbers.1, 2, 3, 4, 5, 6, 8, 9, 10, 1210

Note:  app

  1. 1 is typically treated as an ugly number.
  2. n does not exceed 1690.

Hint:post

  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).

 

這道題是以前那道 Ugly Number 的拓展,這裏讓找到第n個醜陋數,還好題目中給了不少提示,基本上至關於告訴咱們解法了,根據提示中的信息,醜陋數序列能夠拆分爲下面3個子列表:url

(1) 1x2,  2x2, 2x2, 3x2, 3x2, 4x2, 5x2...
(2) 1x3,   1x3, 2x3, 2x3, 2x3, 3x3, 3x3...
(3) 1x5,  1x5, 1x5, 1x5, 2x5, 2x5, 2x5...

仔細觀察上述三個列表,能夠發現每一個子列表都是一個醜陋數分別乘以 2,3,5,而要求的醜陋數就是從已經生成的序列中取出來的,每次都從三個列表中取出當前最小的那個加入序列,請參見代碼以下:spa

 

解法一:code

class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> res(1, 1);
        int i2 = 0, i3 = 0, i5 = 0;
        while (res.size() < n) {
            int m2 = res[i2] * 2, m3 = res[i3] * 3, m5 = res[i5] * 5;
            int mn = min(m2, min(m3, m5));
            if (mn == m2) ++i2;
            if (mn == m3) ++i3;
            if (mn == m5) ++i5;
            res.push_back(mn);
        }
        return res.back();
    }
};

 

咱們也能夠使用最小堆來作,首先放進去一個1,而後從1遍歷到n,每次取出堆頂元素,爲了確保沒有重複數字,進行一次 while 循環,將此時和堆頂元素相同的都取出來,而後分別將這個取出的數字乘以 2,3,5,並分別加入最小堆。這樣最終 for 循環退出後,堆頂元素就是所求的第n個醜陋數,參見代碼以下:htm

 

解法二:blog

class Solution {
public:
    int nthUglyNumber(int n) {
        priority_queue<long, vector<long>, greater<long>> pq;
        pq.push(1);
        for (long i = 1; i < n; ++i) {
            long t = pq.top(); pq.pop();
            while (!pq.empty() && pq.top() == t) {
                t = pq.top(); pq.pop();
            }
            pq.push(t * 2);
            pq.push(t * 3);
            pq.push(t * 5);
        }
        return pq.top();
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/264

 

相似題目:

Super Ugly Number

Ugly Number

Happy Number

Count Primes

Merge k Sorted Lists

Perfect Squares

 

參考資料:

https://leetcode.com/problems/ugly-number-ii/

https://leetcode.com/problems/ugly-number-ii/discuss/69372/Java-solution-using-PriorityQueue

https://leetcode.com/problems/ugly-number-ii/discuss/69364/My-16ms-C%2B%2B-DP-solution-with-short-explanation

https://leetcode.com/problems/ugly-number-ii/discuss/69368/Elegant-C%2B%2B-Solution-O(N)-space-time-with-detailed-explanation.

 

LeetCode All in One 題目講解彙總(持續更新中...)

相關文章
相關標籤/搜索