|
| 1 | +# Perfect Squares |
| 2 | + |
| 3 | +Given an integer, n, return the least number of perfect square numbers that sum to n. |
| 4 | + |
| 5 | +> A perfect square is an integer that is the square of an integer. In other words, it is an integer that is the result of |
| 6 | +> multiplying a whole integer by itself. For example, 1, 4, 9 and 16 are perfect squares, but 3, 5, and 11 are not. |
| 7 | +
|
| 8 | +## Constraints |
| 9 | + |
| 10 | +- 1 <= `n` < 10^3 |
| 11 | + |
| 12 | +## Solution |
| 13 | + |
| 14 | +One of the first solutions that comes to mind is to keep subtracting perfect squares (like 9, 16, 25, …) until we reach |
| 15 | +zero, counting how many times it takes. But that greedy idea doesn’t always find the smallest number of squares. For |
| 16 | +example, trying the biggest square each time may miss a better combination. Instead, this problem has a clever |
| 17 | +mathematical shortcut that utilizes some deep results from number theory, specifically the Four-Square theorem and the |
| 18 | +Three-Square theorem. |
| 19 | + |
| 20 | +The Four-Square theorem says every number can be written as the sum of at most four perfect squares. So, the answer will |
| 21 | +always be one of 1, 2, 3, or 4. The Three-Square theorem tells us that some numbers can’t be expressed as the sum of |
| 22 | +three squares, and these are exactly the numbers that look like 4^a(8b+7) That means, if a number (after dividing out |
| 23 | +all factors of 4) is of the form 8b+7, then it needs four squares. Using these ideas, we can build a simple check-and-decide |
| 24 | +algorithm instead of trying all combinations. First, we remove all factors of 4 from the number, because multiplying or |
| 25 | +dividing by 4 doesn’t change how many squares are needed; it just scales them. Then, we check the remainder when divided |
| 26 | +by 8. If it’s 7, the number must have four squares. Otherwise, we check if it’s already a perfect square (then the answer |
| 27 | +is 1). If not, we test if it can be written as the sum of two perfect squares (then the answer is 2). If none of those |
| 28 | +conditions are true, we know from the theorems that it must be 3. So, rather than testing every combination, this |
| 29 | +approach uses mathematical reasoning to narrow the answer step by step, making it very fast and elegant. |
| 30 | + |
| 31 | +Let’s look at the algorithm steps: |
| 32 | + |
| 33 | +- Keep dividing n by 4 while it is divisible by 4. This simplifies the number without changing the answer. If a number |
| 34 | + is built from perfect squares, then four times that number is built from the same squares, just doubled. So, dividing |
| 35 | + by 4 doesn’t affect how many squares we need; it only makes the number smaller to work with. |
| 36 | +- If the reduced number has a remainder of 7 when divided by 8 (n % 8 == 7), return 4 immediately, because it must need |
| 37 | + four squares. |
| 38 | +- Check if n is a perfect square itself. If yes, return 1. |
| 39 | + - Try to write n as a sum of two perfect squares. Iterate over all possible i from 1 to √n, and check if n - i² is also |
| 40 | + a perfect square. If such a pair exists, return 2. |
| 41 | +- If none of the above conditions are true, return 3. By elimination, the number can be expressed as the sum of three |
| 42 | + squares. |
| 43 | + |
| 44 | +### Time Complexity |
| 45 | + |
| 46 | +We check if the number can be decomposed into the sum of two squares, which takes O(sqrt(n)) iterations. In the remaining |
| 47 | +cases, we perform the check in constant time. |
| 48 | + |
| 49 | +### Space Complexity |
| 50 | + |
| 51 | +The algorithm consumes a constant space, regardless of the size of the input number, so O(1). |
0 commit comments