A clear explanation of checking whether a number equals the sum of its positive divisors excluding itself.
Problem Restatement
A positive integer is called a perfect number if the sum of its positive divisors excluding itself equals the number.
We are given an integer num.
We need to determine whether num is a perfect number.
The official problem defines a perfect number as a positive integer equal to the sum of all its positive divisors excluding itself. (leetcode.com)
Input and Output
| Item | Meaning |
|---|---|
| Input | An integer num |
| Output | True or False |
| Goal | Check whether num is perfect |
Function shape:
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
...Examples
Example 1:
num = 28The positive divisors excluding 28 are:
1, 2, 4, 7, 14Their sum is:
1 + 2 + 4 + 7 + 14 = 28So the answer is:
TrueExample 2:
num = 7The divisors excluding 7 are:
1Their sum is:
1Since:
1 != 7the answer is:
FalseFirst Thought: Check Every Divisor
A direct approach is to try every number from 1 to num - 1.
If a number divides num, add it to the sum.
total = 0
for d in range(1, num):
if num % d == 0:
total += dFinally:
return total == numThis works, but it is inefficient for large numbers.
Problem With Brute Force
The brute force solution checks almost every smaller number.
That costs:
O(n)However, divisors appear in pairs.
For example, if:
28 % 2 == 0then:
28 / 2 = 14So discovering divisor 2 also gives divisor 14.
This means we only need to search up to:
√numKey Insight
If:
d divides numthen:
num // dis also a divisor.
Divisors come in symmetric pairs around the square root.
For example:
| Divisor | Paired divisor |
|---|---|
| 2 | 14 |
| 4 | 7 |
for:
28So we can find all divisors by checking only numbers from:
2 to √numThe divisor 1 is always included for numbers greater than 1.
Algorithm
Handle small values first.
A perfect number must be positive and greater than 1.
So:
if num <= 1:
return FalseInitialize:
total = 1because 1 is always a divisor.
Then iterate:
for d in range(2, int(num ** 0.5) + 1):If d divides num:
- Add
d - Add its paired divisor
num // d
Be careful with perfect squares.
If:
d * d == numthen both divisors are the same, so add it only once.
Finally:
return total == numCorrectness
The algorithm checks every integer d from 2 to √num.
Whenever d divides num, both:
dand:
num // dare positive divisors of num.
Every divisor greater than √num is paired with a divisor smaller than √num, so no divisor is missed.
The divisor 1 is included separately at initialization.
For perfect squares, the square root divisor appears only once, and the algorithm correctly avoids double-counting it.
Therefore total equals the sum of all positive divisors excluding num itself.
The algorithm returns True exactly when this sum equals num, which matches the definition of a perfect number.
Complexity
| Metric | Value | Why |
|---|---|---|
| Time | O(√n) | Only checks divisors up to the square root |
| Space | O(1) | Uses constant extra memory |
Implementation
class Solution:
def checkPerfectNumber(self, num: int) -> bool:
if num <= 1:
return False
total = 1
limit = int(num ** 0.5)
for d in range(2, limit + 1):
if num % d == 0:
total += d
pair = num // d
if pair != d:
total += pair
return total == numCode Explanation
Numbers less than or equal to 1 cannot be perfect:
if num <= 1:
return FalseThe divisor 1 is always included:
total = 1We only check divisors up to the square root:
limit = int(num ** 0.5)If d divides num:
if num % d == 0:then d is a divisor:
total += dand its paired divisor is:
pair = num // dFor non-square cases, add the paired divisor too:
if pair != d:
total += pairFinally, compare the divisor sum with the original number:
return total == numTesting
def test_check_perfect_number():
s = Solution()
assert s.checkPerfectNumber(28) is True
assert s.checkPerfectNumber(6) is True
assert s.checkPerfectNumber(496) is True
assert s.checkPerfectNumber(7) is False
assert s.checkPerfectNumber(1) is False
assert s.checkPerfectNumber(12) is False
print("all tests passed")Test meaning:
| Test | Why |
|---|---|
28 | Standard perfect number |
6 | Smallest perfect number |
496 | Larger known perfect number |
7 | Prime number case |
1 | Special invalid case |
12 | Ordinary composite number |