一、题目描述
对于一个 正整数,如果它和除了它自身以外的所有 正因子 之和相等,我们称它为 「完美数」。
给定一个 整数 n, 如果是完美数,返回 true;否则返回 false。
示例 1:
输入:num = 28 输出:true 解释:28 = 1 + 2 + 4 + 7 + 14 1, 2, 4, 7, 和 14 是 28 的所有正因子。
示例 2:
输入:num = 7 输出:false
提示:
1 <= num <= 10^8
二、解题思路
- 首先,如果 num 小于等于 1,直接返回 false,因为 1 以下的数不可能是完美数。
- 从 2 开始遍历到 sqrt(num),因为一个数的因子如果大于它的平方根,那么另一个因子必然小于等于平方根。
- 对于每个 i,如果 i 是 num 的因子,那么 num/i 也是 num 的因子。将这两个因子累加到 sum 中。
- 注意,如果 i 等于 num/i,即 i 是 num 的平方根,那么只能累加一次,避免重复计算。
- 遍历完成后,判断 sum 是否等于 num,如果相等,返回 true,否则返回 false。
三、具体代码
class Solution {public boolean checkPerfectNumber(int num) {// 小于等于1的数不可能是完美数if (num <= 1) {return false;}int sum = 1; // 1是所有正整数的因子,从1开始累加// 遍历到sqrt(num)即可for (int i = 2; i * i <= num; i++) {if (num % i == 0) { // 如果i是num的因子sum += i; // 累加因子iif (i != num / i) { // 如果i不等于num/i,避免重复累加sum += num / i; // 累加另一个因子num/i}}}// 判断累加的因子和是否等于numreturn sum == num;}
}
四、时间复杂度和空间复杂度
1. 时间复杂度
- 初始化
sum变量是一个常数时间操作,时间复杂度为 O(1)。 - 循环从 2 开始,直到
i * i <= num,循环的次数与num的平方根成正比,因此循环的时间复杂度为 O(√num)。 - 循环内部的操作包括取余、加法以及条件判断,这些都是常数时间操作,不影响循环的时间复杂度。
综上所述,总的时间复杂度为 O(√num)。
2. 空间复杂度
- 该算法使用了固定的几个变量(
num,sum,i),这些变量占用常数大小的空间。 - 算法没有使用额外的数据结构,如数组、集合或递归调用栈等。
因此,总的空间复杂度为 O(1),即常数空间复杂度。
五、总结知识点
-
基础语法:
- 类定义(
class关键字)。 - 方法定义(
public访问修饰符,返回类型boolean,方法名checkPerfectNumber,参数列表)。 - 变量声明与初始化(
int sum = 1;)。
- 类定义(
-
控制流:
- 条件判断(
if语句)。 - 循环结构(
for循环)。
- 条件判断(
-
数学运算:
- 取余操作(
%)用于判断一个数是否是另一个数的因子。 - 乘法操作(
*)用于计算平方根的上界。 - 加法操作(
+)用于累加因子。
- 取余操作(
-
逻辑操作:
- 不等操作符(
!=)用于比较两个数是否不相等,避免在累加因子时重复计算。
- 不等操作符(
以上就是解决这个问题的详细步骤,希望能够为各位提供启发和帮助。
