# LeetCode - 507. Perfect Number ###### tags: `LeetCode` `Guide` `C++` `Easy` > 原題連結: https://leetcode.com/problems/perfect-number/ > Difficulty: <span style="color: green;">Easy</span> ## 題目說明 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 1. #### Input: ``` 28 ``` #### Output: ``` True ``` #### Explanation: ``` 28 = 1 + 2 + 4 + 7 + 14 ``` #### Note: ``` The input number **n** will not exceed 100,000,000. (1e8) ``` ## 說明 這題其實還蠻尷尬的,實際上不太像是在考你code,偏向數學的成分居多。 總之就是要檢查**完全數**,完全數就是把這個數本身的因數(不包含自己)全部相加,最後得到的總和會正好等於自己。 例如: 6的因數有1、2、3、6,因為不包含自己,所以只計算1+2+3,得到6自己,所以6就是一個完全數。 題目會給一個數字,試著檢查它是不是完全數。 ## Code與解析 ### 作法1. Brute Force <span style="font-size:5px; color:green;">[Accept]</span> <span style="font-size:5px; color:orange;">[TimeLimitExceed]</span> > Runtime: 1180 ms > faster than 26.76% > Memory: 8 MB > less than 100.00% ```cpp= class Solution { public: bool checkPerfectNumber(int num) { if(num <= 1) return false; int sum = 1; for(int i = 2; i <= num / 2; i++){ if(num % i == 0) sum += i; } return sum == num; } }; ``` 作法1是最為直觀的暴力破解,從1開始到num的一半為止(剩下的一定不是因數)全部檢查一遍,最後檢查因數總和。然而,當num本身足夠大的時候,要計算比對的次數就會激增,從而導致TLE,顯然有其他方法。 > p.s. 2020/01/03 重新上傳一次code,可以得到AC,可能把時限放寬了,但理論上應該要TLE。 ### 作法2. Optimal Solution <span style="font-size:5px; color:green;">[Accept]</span> > Runtime: 0 ms > faster than 100.00% > Memory: 8 MB > less than 100.00% ```cpp= class Solution { public: bool checkPerfectNumber(int num) { if(num <= 1) return false; int sum = 1, i = 2; for(i = 2; i * i < num; i++){ if(num % i == 0) { sum += i; sum += num / i; } } if(i * i == num) sum += i; return sum == num; } }; ``` 與作法1不同的是,作法2的迴圈的範圍限制在了i * i < num。 理由是這樣的,因為我們今天所找的是因數,基本上,因數必定是成對出現的,只有一個情況除外:i * i = num的i本身。 因此如果我們確定i是因數,那num/i也一定是因數,並且只要檢查到$\sqrt {num}$即可