313. Super Ugly Number

Description

Write a program to find the nth super ugly number.

Super ugly numbers are positive numbers whose all prime factors are in the given prime list primes of size k. For example, [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32]is the sequence of the first 12 super ugly numbers given primes = [2, 7, 13, 19] of size 4.

Note:
(1) 1 is a super ugly number for any given primes.
(2) The given numbers in primes are in ascending order.
(3) 0 < k ≤ 100, 0 < n ≤ 106, 0 < primes[i] < 1000.
(4) The nth super ugly number is guaranteed to fit in a 32-bit signed integer.

Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.

Solution

DP

跟"264. Ugly Number II"相同的思路,由3 pointers扩展成pointers array。依然要注意去重!

class Solution {
    public int nthSuperUglyNumber(int n, int[] primes) {
        int[] uglyNums = new int[n];
        int k = primes.length;
        int[] indexes = new int[k];
        uglyNums[0] = 1;
        
        for (int i = 1; i < n; ++i) {
            uglyNums[i] = Integer.MAX_VALUE;
            
            for (int j = 0; j < k; ++j) {
                uglyNums[i] = Math.min(uglyNums[i]
                                       , primes[j] * uglyNums[indexes[j]]);
            }
            
            for (int j = 0; j < k; ++j) {
                if (primes[j] * uglyNums[indexes[j]] == uglyNums[i]) {
                    ++indexes[j];
                }
            }
        }
        
        return uglyNums[n - 1];
    }
}

minHeap

也可以用heap做。

class Solution {
    public int nthSuperUglyNumber(int n, int[] primes) {
        int[] uglyNums = new int[n];
        PriorityQueue queue
            = new PriorityQueue<>((a, b) -> a.v - b.v);
        uglyNums[0] = 1;
        for (int prime : primes) {
            queue.offer(new Tuple(0, prime, prime));
        }
        
        for (int i = 1; i < n; ++i) {
            uglyNums[i] = queue.peek().v;
            // deal with duplicates
            while (!queue.isEmpty() && queue.peek().v == uglyNums[i]) { 
                Tuple curr = queue.poll();
                queue.offer(new Tuple(curr.i + 1, curr.p
                                      , uglyNums[curr.i] * curr.p));
            }
        }
        
        return uglyNums[n - 1];
    }
    
    class Tuple {
        int i;      // index in uglyNums
        int p;      // prime
        int v;      // value
        
        public Tuple(int i, int p, int v) {
            this.i = i;
            this.p = p;
            this.v = v;
        }
    }
}

你可能感兴趣的:(313. Super Ugly Number)