[LintCode/LeetCode] Super Ugly Number

295 查看

Problem

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.

Notice

1 is a super ugly number for any given primes.
The given numbers in primes are in ascending order.
0 < k ≤ 100, 0 < n ≤ 10^6, 0 < primes[i] < 1000

Example

Given n = 6, primes = [2, 7, 13, 19] return 13

Note

建两个新数组,一个存ugly数,一个存index。ugly数从1开始,后面的是只包含于primes[]中因数的乘积,如例子中取n = 9,则ugly = [1, 2, 4, 7, 8, 13, 14, 16, 19],ugly[8] = 19。index数组中所有元素初值都是0。

实现的过程是,一个for循环里包含两个子循环。看上去不是很容易理解。简而言之,对i来说,每个循环给ugly[i]赋值。两个子循环的作用分别是,遍历primes数组与ugly[index[j]]相乘找到最小乘积存入ugly[i];再遍历一次primes数组与ugly[index[j]]的乘积,结果与ugly[i]相同的,就将index[j]加1,即跳过这个结果(相同结果只存一次)。

Solution

public class Solution {
    public  int nthSuperUglyNumber(int n, int[] primes) {
        int[] ugly = new int[n];
        int[] index = new int[primes.length];
        ugly[0] = 1;
        for (int i = 1; i < n; i++) {
        //find next
            ugly[i] = Integer.MAX_VALUE;
            for (int j = 0; j < primes.length; j++)
                ugly[i] = Math.min(ugly[i], primes[j] * ugly[index[j]]);
        //slip duplicate
            for (int j = 0; j < primes.length; j++) {
                while (primes[j] * ugly[index[j]] == ugly[i]) index[j]++;
            }
        }
        return ugly[n - 1];
    }
}