/**
 * 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:
 *
 * 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.
 *
 * An ugly number must be multiplied by either 2, 3, or 5 from a smaller ugly number.
 *
 * 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.
 *
 * Assume you have Uk, the kth ugly number. Then Uk+1 must be Min(L1 * 2, L2 * 3, L3 * 5).
 *
 * Tags: Dynamic Programming, Heap, Math
 *
 * Similar Problems: (H) Merge k Sorted Lists, (E) Count Primes, (E) Ugly Number, (M) Perfect Squares, (M) Super Ugly
 * Number
 */
public class UglyNumber2 {

    public int nthUglyNumber(int n) {
        if (n <= 0) return -1;
        if (n == 1) return 1;

        // pointers for 2, 3, 5
        int p2 = 0;
        int p3 = 0;
        int p5 = 0;

        // generate ugly numbers array
        int[] uglyNums = new int[n];
        uglyNums[0] = 1;
        for (int i = 1; i < n; i++) {
            uglyNums[i] = Math.min(uglyNums[p2] * 2, Math.min(uglyNums[p3] * 3, uglyNums[p5] * 5));
            // update indices
            if (uglyNums[i] == uglyNums[p2] * 2) p2++;
            if (uglyNums[i] == uglyNums[p3] * 3) p3++;
            if (uglyNums[i] == uglyNums[p5] * 5) p5++;
        }
        return uglyNums[n - 1];
    }
}

add 264 Ugly Number 2