[Medium] 279. Perfect Squares
Given an integer n, return the least number of perfect square numbers that sum to n.
A perfect square is an integer that is the square of an integer; in other words, it is the product of some integer with itself. For example, 1, 4, 9, and 16 are perfect squares while 3 and 11 are not.
Examples
Example 1:
Input: n = 12
Output: 3
Explanation: 12 = 4 + 4 + 4.
Example 2:
Input: n = 13
Output: 2
Explanation: 13 = 4 + 9.
Example 3:
Input: n = 1
Output: 1
Constraints
1 <= n <= 10^4
Thinking Process
- Mathematical approach: Fastest but requires number theory knowledge
- Define state: what subproblem does
dp[i](ordp[i][j]) represent? - Recurrence: how does the answer build from smaller indices?
- Base cases first; optimize space if only prior row/layer is needed.
Common Approaches
Typical techniques for this pattern:
| Approach | Time | Space | Notes |
|---|---|---|---|
| 1D DP (this problem) | O(n) | O(n) or O(1) | Linear recurrence |
| 2D DP | O(nm) | O(nm) or O(n) | Grid or two-sequence problems |
| State machine DP | O(n) | O(1) | Buy/sell, hold/not-hold states |
| Memoization (top-down) | Same as DP | O(n) | Recursive + cache |
Solution
Time Complexity: O(√n)
Space Complexity: O(1)
This solution uses Legendre’s three-square theorem and Lagrange’s four-square theorem to determine the minimum number of perfect squares needed.
import math
class Solution:
def isSquare(self, n):
sq = int(math.sqrt(n))
return n == sq * sq
def numSquares(self, n):
# Reduce n by removing factors of 4
while n % 4 == 0:
n //= 4
# Legendre's three-square theorem: n = 4^a(8b + 7)
# If n ≡ 7 (mod 8), then n requires 4 squares
if n % 8 == 7:
return 4
# Check if n is a perfect square (requires 1 square)
if self.isSquare(n):
return 1
# Check if n can be expressed as sum of 2 squares
i = 1
while i * i <= n:
if self.isSquare(n - i * i):
return 2
i += 1
# Otherwise, requires 3 squares (Legendre's theorem)
return 3
Solution Explanation
Approach: 1D DP (this problem)
Key idea: 1. Mathematical approach: Fastest but requires number theory knowledge
How the code works:
- Mathematical approach: Fastest but requires number theory knowledge
- Define state: what subproblem does
dp[i](ordp[i][j]) represent? - Recurrence: how does the answer build from smaller indices?
- Base cases first; optimize space if only prior row/layer is needed.
- Define state: what subproblem does
Walkthrough — input n = 12, expected output 3:
12 = 4 + 4 + 4.
| Solution | Time | Space | Notes |
|---|---|---|---|
| Mathematical | O(√n) | O(1) | Fastest, requires math knowledge |
| DP | O(n×√n) | O(n) | Standard approach |
| BFS | O(n×√n) | O(n) | Graph-based approach |
| Optimized DP | O(n×√n) | O(n) | Better for multiple queries |
How Solution 1 Works
- Reduce by factors of 4:
- If
n = 4^a × m, thennumSquares(n) = numSquares(m) - This optimization reduces the problem size
- If
- Check for 4 squares (Legendre’s three-square theorem):
- If
n ≡ 7 (mod 8), thennrequires exactly 4 perfect squares - This is a necessary and sufficient condition
- If
- Check for 1 square:
- If
nis a perfect square, return 1
- If
- Check for 2 squares:
- Try all possible
isuch thati² ≤ n - Check if
n - i²is also a perfect square - If yes, return 2
- Try all possible
- Otherwise, return 3:
- By Legendre’s theorem, any number not covered above requires 3 squares
Mathematical Background
Lagrange’s Four-Square Theorem: Every natural number can be represented as the sum of four integer squares.
Legendre’s Three-Square Theorem: A natural number can be expressed as the sum of three squares if and only if it is not of the form 4^a(8b + 7) for nonnegative integers a and b.
Two-Square Theorem: A number can be expressed as the sum of two squares if and only if in its prime factorization, every prime of the form 4k + 3 occurs with an even exponent.
Example Walkthrough
Input: n = 12
Solution 1 (Mathematical):
Step 1: Reduce by 4
12 % 4 = 0 → n = 12 / 4 = 3
3 % 4 = 3 ≠ 0, stop
Step 2: Check 4 squares
3 % 8 = 3 ≠ 7, continue
Step 3: Check 1 square
isSquare(3)? No (1²=1, 2²=4 > 3)
Step 4: Check 2 squares
i=1: 3 - 1 = 2, isSquare(2)? No
i=2: 3 - 4 = -1 < 0, stop
No 2-square representation found
Step 5: Return 3
Result: 3
Solution 2 (DP):
Squares: [1, 4, 9]
dp[0] = 0
dp[1] = 1 (1)
dp[2] = 2 (1+1)
dp[3] = 3 (1+1+1)
dp[4] = 1 (4)
dp[5] = 2 (4+1)
dp[6] = 3 (4+1+1)
dp[7] = 4 (4+1+1+1)
dp[8] = 2 (4+4)
dp[9] = 1 (9)
dp[10] = 2 (9+1)
dp[11] = 3 (9+1+1)
dp[12] = 3 (4+4+4)
Result: 3
Complexity
| Solution | Time | Space | Notes | |———-|——|——-|——-| | Mathematical | O(√n) | O(1) | Fastest, requires math knowledge | | DP | O(n×√n) | O(n) | Standard approach | | BFS | O(n×√n) | O(n) | Graph-based approach | | Optimized DP | O(n×√n) | O(n) | Better for multiple queries |
Common Mistakes
- Perfect square:
n = 1, 4, 9, 16, ...→ return 1 - Sum of 2 squares:
n = 2, 5, 10, 13, ...→ return 2 - Sum of 3 squares:
n = 3, 6, 11, 12, ...→ return 3 - Sum of 4 squares:
n = 7, 15, 23, ...→ return 4 -
Large n:
n = 10^4→ all solutions handle efficiently - Not reducing by 4: Missing the optimization step
- Wrong modulo check: Using
n % 8 == 7incorrectly - Integer overflow: Not handling large squares correctly
- DP initialization: Forgetting to set
dp[0] = 0 - Square generation: Not generating all squares up to
n
Optimization Tips
- Pre-compute squares: Generate perfect squares once
- Early termination: In DP, can break early if
dp[i] == 1 - Static DP: Use static array for multiple queries
- Mathematical shortcuts: Use Legendre’s theorem when possible
Related Problems
- 322. Coin Change - Similar DP pattern
- 377. Combination Sum IV - Count combinations
- 518. Coin Change 2 - Count ways
- 91. Decode Ways - DP with constraints
Pattern Recognition
This problem demonstrates multiple patterns:
- Mathematical Optimization: Using number theory to optimize
- Unbounded Knapsack: Similar to coin change (unlimited use)
- Shortest Path: BFS finds minimum steps
- Dynamic Programming: Building solution from subproblems
Real-World Applications
- Cryptography: Number theory applications
- Optimization: Resource allocation problems
- Algorithm Design: Pattern matching in DP problems
- Mathematical Research: Number representation problems
References
- LC 279: Perfect Squares on LeetCode
- LeetCode Discuss — LC 279: Perfect Squares
- LeetCode Editorial (may require premium)
Key Takeaways
- Mathematical approach: Fastest but requires number theory knowledge
- DP approach: Most intuitive, similar to coin change
- BFS approach: Natural for shortest path problems
- Optimization: Reducing by factors of 4 doesn’t change the answer
- Upper bound: Maximum answer is 4 (Lagrange’s theorem)