题目
解答
大致的思路是,通过循环将 n 这个数去除以 {2,3,5} ,如果能整除就进行递归 将 n 除以 {2,3,5} 传入,通过这样将数逐渐除到 n == 2 || n == 3 || n == 5 那么就代表是丑数
/**
* 执行用时分布 1 ms 击败 16.33% 复杂度分析 消耗内存分布 39.90 MB 击败 31.12%
*/
public boolean isUgly(int n) {
// 因为 0 没有质因数
// 至于负数,因为丑数的质因数是 {2,3,5}, 负数是需要有 负数 * 正数 = 负数,因此,负数肯定不是丑数
if (n <= 0){
return false;
}
return process(n);
}
public boolean process(int n){
// 1 没有质因数,因此它的全部质因数是 {2, 3, 5} 的空集。习惯上将其视作第一个丑数。
// 这里 n == 2 || n == 3 || n == 5 能到这里的都是能被{2,3,5}整除或者本身 n 的值,那么等于这些的值,也就是丑数了
if (n == 1 || n == 2 || n == 3 || n == 5){
return true;
}
for (int prime : primes) {
// 如果能整除
if (n % prime == 0){
// 递归获取结果
boolean process = process(n / prime);
// 如果是整数,那么直接返回,不进行后续的计算
if (process){
return true;
}
}
}
return false;
}
优化
看了官解之后,惭愧,上面的代码,我是想着他会有多种式子,只要一个式子除到最后等于 {2,3,5} 就直接返回,但是官解他是直接将数去除以 {2,3,5} 能除就往下
40 = 2 * 2 * 5,我可以先除以 5,也可以直接除以 2,先除 {2,3,5} 哪一个,最后结果集肯定是 {2,2,5}只是顺序不一样
官解链接:. - 力扣(LeetCode)
/**
* 执行用时分布 0 ms 击败 100.00% 复杂度分析 消耗内存分布 40.00 MB 击败 7.60%
*/
public boolean isUgly(int n) {
// 因为 0 没有质因数
// 至于负数,因为丑数的质因数是 {2,3,5}, 负数是需要有 负数 * 正数 = 负数,因此,负数肯定不是丑数
if (n <= 0){
return false;
}
// 丑数的质因数
int[] primes = new int[]{2, 3, 5};
// 将 n 除以 prime 直到 他不是整数,就换下一个数
for (int prime : primes) {
while (n % prime == 0){
n /= prime;
}
}
return n == 1;
}