力扣508 完美数

力扣508 完美数

原题链接
评论区那些个switch case的就不要抖机灵了!!!😄

首先最最最开始会不自觉想到但又不好意思去写的遍历办法,,

class Solution {
    public boolean checkPerfectNumber(int num) {

        int sum = 0;
        for(int i =1;i<num;i++){
            if(num%i==0){
                sum = sum + i;
            }
        }

        if(sum==num) return true ;
        return false;
    }
}

考虑到时间复杂度为 n。。。。。。

image-20220101001734562

可这用时未免太高,,,,,,,

稍微想一想,
$$
\sqrt{}
$$

(妈的 博客园 不识别 latex 上边是根号)

是个分水岭 把成对的数分成两边。

于是从1到n 变成了从1到根号n

class Solution {
    public boolean checkPerfectNumber(int num) {
        if(num==1) return false;
        int i = 2;
        int end = (int)Math.sqrt(num);
        int sum = 0;
        while(i<=end){
            if(num%i==0) sum+=(i+num/i);i++;
        }
        sum+=1;
        return ((end-(int)end)<1e-6)?(sum==num):((sum-end)==num);

    }
}

想法固然好 隐藏bug却不少。。。

迭代终止条件得到根号n , 那这个取<= 的话 对于平方数 36 比如:

那么这个6 会加重复,所以得区别对待,

还有这个等于0 不能写==0 应该写<无限小,,,,,不然会出错!!!!!!

果然差距不少!!!!

image-20220101001641183

于是好奇我就看了看1ms的其他代码 ,巧了也差不多一个意思吧。。。

class Solution {
    public boolean checkPerfectNumber(int num) {
        int result = 1;
        int x = (int)Math.sqrt(num);
        for(int i = 2; i <= x; i++){
            if(num % i == 0){
                result += i + (num / i);
            }
        }
        if(num == (x * x)) result -= x;
        if(result == num) return true;
        else return false;
    }
}
//转载自 力扣
posted @ 2022-01-01 00:22  淮南枳  阅读(53)  评论(0)    收藏  举报