丑数
写一个程序来检测一个整数是不是丑数。
丑数的定义是,只包含质因子 2, 3, 5 的正整数。比如 6, 8 就是丑数,但是 14 不是丑数以为他包含了质因子 7。
这里就不多赘述思路了,因为1也是一个丑数,但判断的时候可以不用特例化。
public class Solution {
public boolean isUgly(int num) {
if(num == 0){
return false;
}
while (true) {
if (num % 2 == 0) {
num /= 2;
continue;
}
if (num % 3 == 0) {
num /= 3;
continue;
}
if (num % 5 == 0) {
num /= 5;
continue;
} else {
break;
}
}
return num == 1;
}
}
超级丑数
写一个程序来找第 n 个超级丑数。
超级丑数的定义是正整数并且所有的质数因子都在所给定的一个大小为 k 的质数集合内。
比如给你 4 个质数的集合 [2, 7, 13, 19], 那么 [1, 2, 4, 7, 8, 13, 14, 16, 19, 26, 28, 32] 是前 12 个超级丑数。
注意事项
1 永远都是超级丑数不管给的质数集合是什么。
给你的质数集合已经按照升序排列。
0 < k ≤ 100, 0 < n ≤ 10^6, 0 < primes[i] < 1000
先声明一下,这道题的解法不是我的原创,只是我在其他平台遇到过了类似的问题,当初解法之精妙,让我始终难以忘怀,所以见到这个题目就给直接写了出来~
思路:(以2,3,5为质数集合为例)
我们准备一个set,先装入1,然后装入给定的质数集合内的所有数。 [1,2,3,5]
**当前第一个数1就是第一个超级丑数。**
将第一个数 1 poll掉,[2,3,5]每个数都乘质数集合内的所有数得到[2,3,5, 4,6,10, 6,9,15, 10,15,25],根据set规则,加上排序得[2,3,4,5,6,9,10,15,25]
**当前第一个数2就是第二个超级丑数。**
重复上面的步骤,每次增加很多数,poll掉第一个数
思路的正确性:
这个方法肯定不会让遗漏任何一个超级丑数。
每次poll第一个数的操作,第n次poll时的第一个数就是我们要求的数
代码如下:
import java.util.Arrays;
import java.util.TreeSet;
public class Solution {
public int nthSuperUglyNumber(int n, int[] primes) {
Arrays.sort(primes);
TreeSet<Integer> temp = new TreeSet<Integer>();
temp.add(1);
for (int i = 1; i < n; i++) {
int tempvalue = temp.first();
for (int j = 0; j < primes.length; j++) {
//在这里是超级丑数可能越界
//也就是说如果10为上限,我们不能用2 * 6 > 10判断
//而是应该用10 / 2 < 6判断
if (Integer.MAX_VALUE / tempvalue < primes[j]) {
break;
}
temp.add(tempvalue * primes[j]);
}
temp.pollFirst();
}
return temp.first();
}
}