超级丑数 是一个正整数,并满足其所有质因数都出现在质数数组 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] 。
1.使用for循环依次遍历的暴力解法,必然超时!
2.动态规划思考
定义数组dp[n],其中dp[i] 表示第 i 个超级丑数,第 n 个超级丑数即为dp[n]。
初始条件:
如何得到后续的dp数组值?
如何得到其余的超级丑数呢?创建与数组primes 相同长度的数组pointers,表示下一个超级丑数是当前指针指向的超级丑数乘以对应的质因数。初始时,数组 pointers 的元素值都是 1。
定义一个与质数数组相同长度的指针数组pointers[m]
当时
对于最小的超级丑数所在的位置,值自动加1。
此处的加1处理的解释:
首先pointers中的元素指向的是dp的索引位置,dp数组最初始的值是超级丑数1。
当第一轮找到新的最小超级丑数后,下一次循环应该使用最新的超级丑数,所以dp的索引应该加1,也就是的值加1
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
int lens= primes.size();
vector<int> dp(n + 1);
dp[1] = 1;
vector<int> pointers(lens, 1);
for (int i = 2; i <= n; i++) {
vector<int> nums(lens);
int minNum = INT_MAX;
for (int j = 0; j < lens; j++) {
nums[j] = dp[pointers[j]] * primes[j];
minNum = min(minNum, nums[j]);
}
dp[i] = minNum;
for (int k = 0; k < lens; k++) {
if (minNum == nums[k]) {
pointers[k]++;
}
}
}
return dp[n];
}
};
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/super-ugly-number
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。