Super Ugly Number
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.
分析
这道题其实是LeetCode另外一道题Ugly Number II的general情况。思路是一样的,首先我们考虑一系列的数字是根据什么原则产生的。很显然,除了第一个数字,其余所有数字都是之前已有数字乘以任意一个在质数数组里的质数.
所以对于每一个已有的数字,我们都可以分别乘以所有在质数数组里的质数得到一系列的数字,这些数字肯定会存在在以后的序列中。由于我们是要得到从小到大的结果,所以我们可以维护个count数组,来记录对于对应质数下一个需要被乘的已有数的index, 我们取最小的结果当做下个数,对于那个最小的结果,需要增加count数组中那个质数对应的index,表明下一次用下个已有的数来乘对应的质数。
有些tricky的地方是对于已有序列中的数,乘不同质数得到的结果会可能存在重复,比如题目中例子2, 7与7, 2就重复了,解决方法很简单,就是只要是等于最小的结果,就增加对应count数组中的元素,具体见代码。
复杂度
time: O(n), space: O(n)
代码
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int[] count = new int[primes.length];
int[] res = new int[n];
res[0] = 1;
for (int i = 1; i < n; i++) {
int min = Integer.MAX_VALUE;
// 找出候选数字的最小值
for (int j = 0; j < primes.length; j++) {
min = Math.min(min, primes[j] * res[count[j]]);
}
res[i] = min;
// 增加与最终结果对应的质数的元素
for (int j = 0; j < count.length; j++) {
// 所有符合条件的,都需增加对应prime index, 避免重复
if (res[count[j]] * primes[j] == min) {
count[j]++;
}
}
}
return res[n - 1];
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。