第3题题目
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.
之前在剑指offer上有看到第二题,即求出前N个丑数,思路构建一个数组,以及三个下标,分别对应2,3,5的目前最大子丑数所在位置。
求新丑数时,分别对单个下标所在的数乘2,3,5求min值,记住之后必须更新所有对应下标。
for循环上述语句。
对于第一题判断是否是丑数则很简单了,2/3/5到除不下去,==1则是丑数。
第三题有点绕,但原理上是和2一样的。输入n个丑数基底,那我们就维护n个对应的下标。
primers:丑数基。
ugly:丑数,按顺序加进去。
index:每个丑数基 对应的 不大于目前丑数 但乘上这个丑数基 就大于目前丑数 的最大丑数 在ugly里面的下标。
按原理来说和ugly2是一样的,只是这里的丑数基个数由输入的实参确定,所以只能在一个for里面再加两个for来更新对应的丑数和丑数基。
代码:
1
class Solution {
public:
bool isUgly(int num) {
if(num==0)
return false;
for(int i=2;i<6;++i)
while(num%i==0)
num=num/i;
return (num==1);
}
};
2
class Solution {
public:
int nthUglyNumber(int n) {
if (n <= 0)
return 0;
int *ugly = new int[n];
ugly[0] = 1;
int index = 1;
int *u2 = ugly;
int *u3 = ugly;
int *u5 = ugly;
while (index < n)
{
ugly[index] = min(*u2 * 2, *u3 * 3, *u5 * 5);
while (*u2 * 2 <= ugly[index])
++u2;
while (*u3 * 3 <= ugly[index])
++u3;
while (*u5 * 5 <= ugly[index])
++u5;
++index;
}
int res = ugly[index - 1];
delete []ugly;
return res;
}
int min(int a, int b, int c)
{
int temp = b < c ? b : c;
return temp < a ? temp : a;
}
};
3
class Solution {
public:
int nthSuperUglyNumber(int n, vector<int>& primes)
{
size_t length = primes.size();
vector<int> index(length, 0);
vector<int> ugly(n, INT_MAX);
ugly[0] = 1;
for (int i = 1; i < n; ++i)
{
for (int j = 0; j < length; ++j)
ugly[i] = min(ugly[i], ugly[index[j]] * primes[j]);
for (int k = 0; k < length; ++k)
{
while (ugly[index[k]] * primes[k] <= ugly[i])
++index[k];
}
}
return ugly[n - 1];
}
};