[LeetCode] 507.Perfect Number 完美数

对于一个 正整数,如果它和除了它自身以外的所有正因子之和相等,我们称它为“完美数”。
给定一个 正整数 n, 如果他是完美数,返回 True,否则返回 False。
注意:输入的数字 n 不会超过 100,000,000. (1e8)
例:输入: 28
输出: True
解释: 28 = 1 + 2 + 4 + 7 + 14

这是一道有关完美数的题目。完美数的定义如上所说,如果一个数n的因数和 (包括n) 记作 f(n),我们把令 f(n) = 2n的数称为完美数,令 f(n) < 2n 的数称为亏数,令 f(n) > 2n 的数称为盈数。

思路

简单的,我们可以得出 1不是完美数。对于 n>1 的情况,考虑一对对的因数相加,例如,对28有[1,28],[2,14],[4,7],因为1必定是n的因子,可以提前加上,那么寻找其他因子的范围缩小至[2, sqrt(n)]。
遍历这一区间,如果数i可以被n整除,那么我们把 i 和 n/i 都加上,当 n 是完全平方数时,相同的因子加了两次(即i与 n/i = i),所以要减掉一次当前的 i。还有就是在遍历的过程中如果累积和sum大于n了,直接返回false即可。代码如下。

代码

class Solution {
public:
    bool checkPerfectNumber(int num) {
        if (num == 1) return false;
        int sum = 1;
        for (int i = 2; i * i <= num; ++i) {
            if (num % i == 0) 
                sum += (i + num / i);
            if (i * i == num)
                sum -= i;
            if (sum > num) 
                return false;
        }
        return sum == num;
    }
};

历史

事实上,完美数的寻找已经颇有历史,从古希腊的毕达哥拉斯到欧拉,再到现代的计算机,不少数学家都在不停地寻找完美数及推测它的性质。由相关数学知识可得,完美数的数量分布极其零散,前七个完美数为6、28、496、8,128、33,550,336、8,589,869,056、137,438,691,328。
对于此题1e8的范围内,仅需判断前五个完美数即可。代码如下。

代码

class Solution {
public:
    bool checkPerfectNumber(int num) {
        return num==6 || num==28 || num==496 || num==8128 || num==33550336;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_43142136/article/details/82949972
今日推荐