Perfect Number - Complete Solution Guide
Perfect Number is LeetCode problem 507, a Easy level challenge. This complete guide provides step-by-step explanations, multiple solution approaches, and optimized code in python3, java, cpp, c.
Problem Statement
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 n , return true if n is a perfect number, otherwise return false . 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
Detailed Explanation
The problem asks us to determine if a given positive integer, `num`, is a perfect number. A perfect number is defined as a number that is equal to the sum of its proper divisors (all positive divisors excluding the number itself). The input is a single integer `num`, and the output should be a boolean value: `true` if `num` is a perfect number, and `false` otherwise. The constraint is that `1 <= num <= 10^8`.
Solution Approach
The provided solution calculates the sum of the proper divisors of the input number `num`. It initializes the sum to 1 because 1 is always a divisor. It then iterates from 2 up to the square root of `num`. For each number `i` in this range, it checks if `i` is a divisor of `num`. If it is, `i` and `num/i` are added to the sum (unless `i * i == num`, in which case only `i` is added to avoid double-counting). Finally, it checks if the sum of the proper divisors is equal to `num`. If it is, then `num` is a perfect number, and the function returns `true`. Otherwise, it returns `false`.
Step-by-Step Algorithm
- Step 1: Handle the base cases: if `num` is less than or equal to 1, return `false` because perfect numbers are greater than 1.
- Step 2: Initialize `sum_div` to 1, as 1 is always a divisor.
- Step 3: Iterate from `i = 2` to the square root of `num` (inclusive).
- Step 4: In each iteration, check if `i` divides `num` without any remainder (i.e., `num % i == 0`).
- Step 5: If `i` is a divisor, add `i` to `sum_div`.
- Step 6: If `i * i != num` (meaning `i` is not the square root of `num`), also add `num // i` to `sum_div`.
- Step 7: After the loop finishes, compare `sum_div` with `num`. If they are equal, return `true`; otherwise, return `false`.
Key Insights
- Insight 1: A naive approach of iterating through all numbers from 1 to `num-1` to find divisors would be too slow. We can optimize this by only iterating up to the square root of `num`.
- Insight 2: When we find a divisor `i` of `num`, then `num/i` is also a divisor. We can add both to the sum of divisors.
- Insight 3: Be careful not to double-count the square root if `num` is a perfect square (i.e., `i * i == num`).
Complexity Analysis
Time Complexity: O(sqrt(n))
Space Complexity: O(1)
Topics
This problem involves: Math.
Companies
Asked at: Accenture, Grammarly.