263. 丑数
思路:数学
对于丑数n,有:
n
=
2
a
⋅
3
b
⋅
5
c
n = 2^a \cdot 3^b \cdot 5^c
n=2a⋅3b⋅5c
因此定义一个2,3,5的vector,当n%2/3/5可以除尽时,就一直除,一直把2/3/5都除了最后比较n是否为1,不为1不是丑数
class Solution {
public:
bool isUgly(int n) {
if (n <= 0) {
return false;
}
vector<int> factors = {2, 3, 5};
for (int factor : factors) {
while (n % factor == 0) {//能除尽
n /= factor;
}
}
return n == 1;
}
};
264. 丑数 II
思路:动态规划
选取3个指针分别表示现在乘了几个2/3/5,将dp[i]取为最小的num,更新指针
class Solution {
public:
int nthUglyNumber(int n) {
if(n == 1) return n;
//dp[i]表示第i个丑数
vector<int> dp(n+1);
int p2=1,p3 = 1,p5 = 1;
dp[1] = 1;
for(int i = 2;i<=n;i++){
int num2 = 2*dp[p2],num3 = 3*dp[p3],num5 = 5*dp[p5];
dp[i] = min(num2,min(num3,num5));
if(dp[i] == num2){
p2++;
}
if(dp[i] == num3){
p3++;
}
if(dp[i] == num5){
p5++;
}
}
return dp[n];
}
};
313. 超级丑数
思想:动态规划(丑数Ⅱ的扩展)
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes) {
vector<long> dp(n + 1);
int m = primes.size();
vector<int> pointers(m, 0);
vector<long> nums(m, 1);
for (int i = 1; i <= n; i++) {
long minNum = INT_MAX;
for (int j = 0; j < m; j++) {
minNum = min(minNum, nums[j]);
}
dp[i] = minNum;
for (int j = 0; j < m; j++) {
if (nums[j] == minNum) {
pointers[j]++;
nums[j] = dp[pointers[j]] * primes[j];
}
}
}
return dp[n];
}
};