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.
Solution 1:
一种比较直观的想法是这样的
每个在dp中的数字都有可能乘以一个prime变成另一个小的数字,所以只需要不断的重复从已有的dp数字中乘以prime,找到下一个最小的可能数值就好
这里需要我们记录每个dp中的数字已经乘以prime的下表,用prime_tot记录,然而发现还是TLE
<span style="font-size:18px;">import java.util.*;
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int dp[] = new int[n];
int prime_tot[] = new int[n];
dp[0] = 1;
int primes_size = primes.length;
for (int i = 1; i < n; i++) {
int min = Integer.MAX_VALUE;
int min_index = 0;
for (int j = 0; j < i; j++) {
if (prime_tot[j] == primes_size)
continue;
if (dp[j] >= min)
break;
int neo = dp[j] * primes[prime_tot[j]];
if (neo < min) {
min = neo;
min_index = j;
}
}
dp[i] = min;
prime_tot[min_index]++;
}
return dp[n - 1];
}
}</span>
Solution 2:
那么不妨换一个思路,每一次的ugly num都是由dp中的某个ugly num和某个prime相乘得到,那么我们只要记录每个prime乘到哪一个dp中的数字即可
import java.util.*;
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
int dp[] = new int[n];
int primes_size = primes.length;
int primes_tot[] = new int[primes_size];
dp[0] = 1;
int tot = 1;
while (tot < n) {
int min = Integer.MAX_VALUE;
int min_index = 0;
for (int j = 0; j < primes_size; j++) {
int neo = dp[primes_tot[j]] * primes[j];
if (neo < min) {
min = neo;
min_index = j;
}
}
dp[tot] = min;
primes_tot[min_index]++;
if (min == dp[tot - 1])
continue;
tot++;
}
return dp[n - 1];
}
public static void main(String[] args) {
int primes[] = { 7, 19, 29, 37, 41, 47, 53, 59, 61, 79, 83, 89, 101,
103, 109, 127, 131, 137, 139, 157, 167, 179, 181, 199, 211,
229, 233, 239, 241, 251 };
Solution s = new Solution();
System.out.println(s.nthSuperUglyNumber(1000, primes));
}
}