Back to blog
May 08, 2025
5 min read

Perfect Number

A perfect number is a positive integer that is equal to the sum of its positive divisors, excluding the number itself.

Difficulty: Easy | Acceptance: 48.80% | Paid: No Topics: Math

A perfect number is a positive integer that is equal to the sum of its positive divisors, excluding the number itself. A divisor of an integer x is an integer that can divide x evenly.

Given an integer num, return true if num is a perfect number, otherwise return false.

Examples

Example 1

Input:

num = 28

Output:

true

Explanation: 28 = 1 + 2 + 4 + 7 + 14 1, 2, 4, 7, and 14 are all divisors of 28.

Example 2

Input:

num = 7

Output:

false

Constraints

1 <= num <= 10^8

Brute Force Iteration

Intuition The most straightforward approach is to iterate through all numbers from 1 to num - 1. For each number, check if it divides num evenly. If it does, add it to a running sum. Finally, compare the sum to num.

Steps

  • Initialize a sum variable to 0.
  • Loop from 1 to num - 1.
  • If num is divisible by the current iterator, add the iterator to the sum.
  • After the loop, return true if sum equals num, otherwise false.
python
class Solution:
    def checkPerfectNumber(self, num: int) -> bool:
        if num <= 1:
            return False
        total_sum = 0
        for i in range(1, num):
            if num % i == 0:
                total_sum += i
        return total_sum == num

Complexity

  • Time: O(N) - We iterate up to N times.
  • Space: O(1) - We only use a variable for the sum.
  • Notes: This approach is inefficient for large numbers (e.g., close to 10⁸) and may result in a Time Limit Exceeded error on LeetCode.

Square Root Optimization

Intuition Divisors come in pairs. If i divides num, then num / i also divides num. For example, for 28, if we find 2, we also find 14. We only need to iterate up to the square root of num to find all divisor pairs.

Steps

  • Handle edge case: if num <= 1, return false.
  • Initialize sum to 1 (since 1 is always a divisor for num > 1).
  • Loop from 2 up to the square root of num.
  • If i divides num:
    • Add i to the sum.
    • If i is not equal to num / i (to avoid adding the square root twice), add num / i to the sum.
  • Return true if sum equals num, otherwise false.
python
class Solution:
    def checkPerfectNumber(self, num: int) -> bool:
        if num <= 1:
            return False
        total_sum = 1
        i = 2
        while i * i <= num:
            if num % i == 0:
                total_sum += i
                if i != num // i:
                    total_sum += num // i
            i += 1
        return total_sum == num

Complexity

  • Time: O(√N) - We iterate only up to the square root of N.
  • Space: O(1) - Constant space usage.
  • Notes: This is the standard optimal approach for general divisor sum problems.

Euclid-Euler Theorem

Intuition According to the Euclid-Euler theorem, every even perfect number can be represented as 2^(p-1) * (2^p - 1), where (2^p - 1) is a prime number (specifically a Mersenne prime). Given the constraint 1 <= num <= 10⁸, there are only a few perfect numbers that exist. We can simply check if the input matches one of these known values.

Steps

  • Identify the list of perfect numbers within the constraint range: 6, 28, 496, 8128, 33550336.
  • Check if the input num exists in this set.
  • Return true if it does, false otherwise.
python
class Solution:
    def checkPerfectNumber(self, num: int) -> bool:
        # Known perfect numbers within the 10^8 limit
        return num in {6, 28, 496, 8128, 33550336}

Complexity

  • Time: O(1) - Set lookup or simple comparison is constant time.
  • Space: O(1) - The set of known numbers is fixed and very small.
  • Notes: This is the fastest solution for this specific problem due to the limited input range, but it relies on mathematical pre-knowledge rather than algorithmic calculation.