[leetcode] Ugly Number II 解题报告

题目链接:https://leetcode.com/problems/ugly-number-ii/

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).
思路:由题目提示可以知道,我们可以依次判断每一个数直到找到第n个丑数,但是因为大多数并不是丑数,由丑数的规律--质因数只有2,3,5,我们可以依次只产生丑数,这样效率会有很大的提高。但是我们要如何保持有序的产生丑数呢?
假设我们现在已经有了一个丑数的有序数组,如果要找到下一个丑数,则可以将数组中的每一个数乘以2,并将其中第一个大于当前丑数的的结果记为M2,同样将当前有序数组每一个数都乘以3,第一个大于当前丑数的的结果记为M3,同样方式得到乘以5的第一个大于当前丑数的结果记为M5。可以下一个丑数必然是min(M2, M3, M5)。
事实上我们并不必要将数组中的每个数都乘以2,3,5。对于乘以2来说,我们只要找到第一个乘以2大于当前丑数的数在数组中的位置,同样找到第一个乘以3,5大于当前丑数的数的位置。如果当前丑数记为M,然后就可以使用min(M*2, M*3, M*5)来产生下一个丑数。
代码如下:
class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> uglyNum;
        uglyNum.push_back(1);
        int l2 = 0;
        int l3 = 0;
        int l5 = 0;
        int nextIndex = 1;

        while(nextIndex  < n)
        {
            int value = min(uglyNum[l2]*2, min(uglyNum[l3]*3, uglyNum[l5]*5));
            uglyNum.push_back(value);
            
            while(uglyNum[l2]*2 <= uglyNum[nextIndex])
                l2++;
            while(uglyNum[l3]*3 <= uglyNum[nextIndex])
                l3++;
            while(uglyNum[l5]*5 <= uglyNum[nextIndex])
                l5++;   
            nextIndex++;
        }
        return uglyNum[nextIndex - 1];
    }
};



你可能感兴趣的:([leetcode] Ugly Number II 解题报告)