【数学】C038_完美数(暴力枚举 | 开平方优化 | 欧几里得定理)

一、题目描述

We define the Perfect Number is a positive integer that
is equal to the sum of all its positive divisors except itself.

Now, given an integer n,
write a function that returns true when it is a perfect number and false when it is not.

Example:
Input: 28
Output: True
Explanation: 28 = 1 + 2 + 4 + 7 + 14
Note: The input number n will not exceed 100,000,000. (1e8)

二、题解

(1) 暴力枚举(超时)

/**
 * @thought:暴力枚举(99999997)
 * @date: 1/18/2020 10:56 AM
 * @Execution info:
 *  ·执行用时  ms 击败了 % 的java用户
 *  ·内存消耗 MB 击败了 % 的java用户
 * @Asymptotic Time Complexity:O(根号num)
 */
public boolean checkPerfectNumber(int num) {
  int sum=0;
  for (int i = 1; i < num; i++) {
    if(num%i==0)
      sum+=i;
  }
  return sum==num;
}

复杂度分析

  • 时间复杂度: O ( n u m ) O(num)
  • 空间复杂度: O ( 1 ) O(1)

(2) 优化暴力

在枚举时,我们只需要从 1 1 s q r t ( n ) sqrt(n) 进行枚举即可。因如果 n 有一个大于 s q r t ( n ) = = N sqrt(n)==N 的因数 x 1 x1 ,那么它一定有一个小于 N 的因数 n / x = = x 2 n/x==x2

此外还需要考虑特殊情况,即 x = n / x x = n/x ,这时我们不能重复计算。因为 N N = = n N*N==n ,如果 x 1 < N x 2 > N x1<N,那么 x2>N

/**
 * @date: 1/18/2020 11:01 AM
 * @Execution info:
 *  ·执行用时 6ms -> 2ms 击败了 32.44% -> 87.68% 的java用户
 *  ·内存消耗 MB 击败了 46.42% 的java用户
 * @Asymptotic Time Complexity:O()
 */
public boolean checkPerfectNumber2(int num) {
  if(num==1)  return false;
  int sum=1;
  double sqltNum = Math.sqrt(num);
//    for (int x = 2; x <= sqltNum; x++) {
//      if(num%x==0)
//        sum+=x + num/x;
//    }
  for (int x = 2; x *x <= num; x++) {
    if(num%x==0)
      sum += x + num/x;
  }
  return sum==num;
}

复杂度分析

  • 时间复杂度: O ( s q r t ( n u m ) ) O(sqrt(num))
  • 空间复杂度: O ( 1 ) O(1)
发布了300 篇原创文章 · 获赞 48 · 访问量 8050

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104034097
今日推荐