class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
}
};
313. 超级丑数
超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 primes
中。
给你一个整数 n
和一个整数数组 primes
,返回第 n
个 超级丑数 。
题目数据保证第 n
个 超级丑数 在 32-bit 带符号整数范围内。
示例 1:
输入:n = 12,primes
=[2,7,13,19]
输出:32 解释:给定长度为 4 的质数数组 primes = [2,7,13,19],前 12 个超级丑数序列为:[1,2,4,7,8,13,14,16,19,26,28,32] 。
示例 2:
输入:n = 1, primes = [2,3,5] 输出:1 解释:1 不含质因数,因此它的所有质因数都在质数数组 primes = [2,3,5] 中。
提示:
1 <= n <= 105
1 <= primes.length <= 100
2 <= primes[i] <= 1000
primes[i]
是一个质数primes
中的所有值都 互不相同 ,且按 递增顺序 排列相似题目
原站题解
python3 解法, 执行用时: 2048 ms, 内存消耗: 18.8 MB, 提交时间: 2022-12-04 12:48:24
class Solution: def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int: m = len(primes) # dp[i] 代表第i+1个丑数 dp = [inf] * n dp[0] = 1 # indexes代表每个质因子现在应该跟哪个丑数相乘 indexes = [0] * m for i in range(1, n): # 哪个质因子相乘的丑数将会变化 changeIndex = 0 for j in range(m): # 如果当前质因子乘它的丑数小于当前的丑数,更新当前丑数并更新变化坐标 if primes[j] * dp[indexes[j]] < dp[i]: changeIndex = j dp[i] = primes[j] * dp[indexes[j]] # 如果相等直接变化,这样可以去重复 elif primes[j] * dp[indexes[j]] == dp[i]: indexes[j] += 1 # 变化的坐标+1 indexes[changeIndex] += 1 return dp[-1]
python3 解法, 执行用时: 476 ms, 内存消耗: 18.7 MB, 提交时间: 2022-12-04 12:48:08
class Solution: def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int: m = len(primes) # dp[i] 代表第i+1个丑数 dp = [1] * n # 丑数, 刚刚乘过的丑数的坐标, 质因数 pq = [(p, 0, i) for i,p in enumerate(primes)] for i in range(1, n): # 目前最新的最小的丑数 dp[i] = pq[0][0] # 所有等于这个值的要全部出队列,并根据该乘的丑数重新加入队列 while pq and pq[0][0] == dp[i]: _, idx, p = heapq.heappop(pq) heapq.heappush(pq, (dp[idx+1] * primes[p], idx + 1, p)) return dp[-1]
java 解法, 执行用时: 80 ms, 内存消耗: 42.1 MB, 提交时间: 2022-12-04 12:47:32
class Solution { public int nthSuperUglyNumber(int n, int[] primes) { int m = primes.length; PriorityQueue<int[]> q = new PriorityQueue<>((a,b)->a[0]-b[0]); for (int i = 0; i < m; i++) { q.add(new int[]{primes[i], i, 0}); } int[] ans = new int[n]; ans[0] = 1; for (int j = 1; j < n; ) { int[] poll = q.poll(); int val = poll[0], i = poll[1], idx = poll[2]; if (val != ans[j - 1]) ans[j++] = val; q.add(new int[]{ans[idx + 1] * primes[i], i, idx + 1}); } return ans[n - 1]; } }
java 解法, 执行用时: 70 ms, 内存消耗: 48.7 MB, 提交时间: 2022-12-04 12:47:21
class Solution { public int nthSuperUglyNumber(int n, int[] primes) { PriorityQueue<Integer> q = new PriorityQueue<>(); q.add(1); while (n-- > 0) { int x = q.poll(); if (n == 0) return x; for (int k : primes) { if (k <= Integer.MAX_VALUE / x) q.add(k * x); if (x % k == 0) break; } } return -1; // never } }
javascript 解法, 执行用时: 140 ms, 内存消耗: 44.7 MB, 提交时间: 2022-12-04 12:46:18
/** * @param {number} n * @param {number[]} primes * @return {number} */ var nthSuperUglyNumber = function(n, primes) { const dp = new Array(n + 1).fill(0); const m = primes.length; const pointers = new Array(m).fill(0); const nums = new Array(m).fill(1); for (let i = 1; i <= n; i++) { let minNum = Number.MAX_SAFE_INTEGER; for (let j = 0; j < m; j++) { minNum = Math.min(minNum, nums[j]); } dp[i] = minNum; for (let j = 0; j < m; j++) { if (nums[j] == minNum) { pointers[j]++; nums[j] = dp[pointers[j]] * primes[j]; } } } return dp[n]; };
golang 解法, 执行用时: 24 ms, 内存消耗: 3.9 MB, 提交时间: 2022-12-04 12:46:04
func nthSuperUglyNumber(n int, primes []int) int { dp := make([]int, n+1) m := len(primes) pointers := make([]int, m) nums := make([]int, m) for i := range nums { nums[i] = 1 } for i := 1; i <= n; i++ { minNum := math.MaxInt64 for j := range pointers { minNum = min(minNum, nums[j]) } dp[i] = minNum for j := range nums { if nums[j] == minNum { pointers[j]++ nums[j] = dp[pointers[j]] * primes[j] } } } return dp[n] } func min(a, b int) int { if a < b { return a } return b }
python3 解法, 执行用时: 760 ms, 内存消耗: 18.8 MB, 提交时间: 2022-12-04 12:45:46
class Solution: def nthSuperUglyNumber(self, n: int, primes: List[int]) -> int: dp = [0] * (n + 1) m = len(primes) pointers = [0] * m nums = [1] * m for i in range(1, n + 1): min_num = min(nums) dp[i] = min_num for j in range(m): if nums[j] == min_num: pointers[j] += 1 nums[j] = dp[pointers[j]] * primes[j] return dp[n]