本文详细解析LeetCode第263题"丑数",这是一道数学问题。文章提供了简洁高效的除法判断解法,包含C#、Python、C++、JavaScript四种语言实现,配有详细的算法步骤图解和性能分析。适合算法初学者和想要掌握基础数学算法的开发者。
核心知识点: 数学运算、除法操作、循环控制
难度等级: 简单
推荐人群: 算法初学者、编程基础学习者
编写一个程序判断给定的数是否为丑数。
丑数就是只包含质因数 2
, 3
, 5
的正整数。
输入: 6
输出: true
解释: 6 = 2 × 3
输入: 8
输出: true
解释: 8 = 2 × 2 × 2
输入: 14
输出: false
解释: 14 不是丑数,因为它包含了另外一个质因数 7。
-2^31 <= num <= 2^31 - 1
1
通常被视为丑数。丑数的定义是只包含质因数 2、3、5 的正整数。根据这个定义,我们可以通过不断除以 2、3 和 5 来检查一个数是否为丑数。如果最后剩下的数是 1,那么这个数就是丑数;否则,它就不是丑数。
核心思想:
num
小于等于 0,则它不是丑数,直接返回 false
num
等于 1,根据定义,它是丑数,直接返回 true
num
能被 2 整除,就将其除以 2;只要 num
能被 3 整除,就将其除以 3;只要 num
能被 5 整除,就将其除以 5算法优化:
复杂度分析:
步骤 | 输入示例 | 操作 | 结果 | 说明 |
---|---|---|---|---|
初始状态 | num = 12 | 检查边界条件 | num > 0,继续 | 12是正数,可能是丑数 |
第一轮 | num = 12 | 除以2直到不能整除 | num = 3 | 12 ÷ 2 ÷ 2 = 3 |
第二轮 | num = 3 | 除以3直到不能整除 | num = 1 | 3 ÷ 3 = 1 |
第三轮 | num = 1 | 除以5直到不能整除 | num = 1 | 1不能被5整除,保持不变 |
结果判断 | num = 1 | 检查是否为1 | true | 最终结果为1,是丑数 |
输入 | 质因数分解 | 处理过程 | 最终结果 | 是否丑数 |
---|---|---|---|---|
6 | 2 × 3 | 6→3→1 | 1 | 是 |
8 | 2³ | 8→4→2→1 | 1 | 是 |
14 | 2 × 7 | 14→7 | 7 | 否(包含质因数7) |
1 | 无 | 直接返回 | 1 | 是(特殊情况) |
0 | 无意义 | 边界检查 | false | 否(非正数) |
public class Solution {
public bool IsUgly(int num) {
// 非正数不是丑数
if (num <= 0) {
return false;
}
// 循环除以2、3、5,直到不能整除为止
int[] factors = {2, 3, 5};
foreach (int factor in factors) {
while (num % factor == 0) {
num /= factor;
}
}
// 如果最后剩下1,则是丑数;否则不是
return num == 1;
}
}
class Solution:
def isUgly(self, num: int) -> bool:
# 非正数不是丑数
if num <= 0:
return False
# 循环除以2、3、5,直到不能整除为止
for factor in [2, 3, 5]:
while num % factor == 0:
num //= factor
# 如果最后剩下1,则是丑数;否则不是
return num == 1
class Solution {
public:
bool isUgly(int num) {
// 非正数不是丑数
if (num <= 0) {
return false;
}
// 循环除以2、3、5,直到不能整除为止
int factors[] = {2, 3, 5};
for (int factor : factors) {
while (num % factor == 0) {
num /= factor;
}
}
// 如果最后剩下1,则是丑数;否则不是
return num == 1;
}
};
/**
* @param {number} num
* @return {boolean}
*/
var isUgly = function(num) {
// 非正数不是丑数
if (num <= 0) {
return false;
}
// 循环除以2、3、5,直到不能整除为止
const factors = [2, 3, 5];
for (const factor of factors) {
while (num % factor === 0) {
num /= factor;
}
}
// 如果最后剩下1,则是丑数;否则不是
return num === 1;
};
语言 | 执行用时 | 内存消耗 | 特点 |
---|---|---|---|
C++ | 0 ms | 5.9 MB | 性能最佳,内存占用最小 |
C# | 24 ms | 15.1 MB | 性能中等,语法简洁清晰 |
Python | 32 ms | 13.6 MB | 代码最简洁,易于理解 |
JavaScript | 68 ms | 38.1 MB | 性能较差,内存占用最大 |
解法 | 时间复杂度 | 空间复杂度 | 优点 | 缺点 |
---|---|---|---|---|
迭代除法 | O(log n) | O(1) | 简单易懂,效率高 | 无明显缺点 |
递归除法 | O(log n) | O(log n) | 代码简洁 | 存在栈溢出风险 |
质因数分解 | O(sqrt(n)) | O(1) | 适用于更一般的因数分解问题 | 对于本题过于复杂 |
算法专题合集 - 查看完整合集
关注合集更新:点击上方合集链接,关注获取最新题解!目前已更新第263题。
感谢大家耐心阅读到这里!希望这篇题解能够帮助你更好地理解和掌握这道算法题。
如果这篇文章对你有帮助,请:
你的支持是我持续分享的动力!
一起进步:算法学习路上不孤单,欢迎一起交流学习!