Perfect Squares
Given an integer n, return the least number of perfect square numbers (1, 4, 9, 16, ...) that sum to n. For example, 12 = 4 + 4 + 4, so the answer is 3. 13 = 9 + 4, so the answer is 2.
This is a classic DP problem with the recurrence: for i from 1 to n, dp[i] = min(dp[i], dp[i - j*j] + 1) for all j*j<= i. The base case is dp[0] = 0.
The solution initializes dp[i] = i (worst case: i = 1+1+...+1 with i ones). For each i, try subtracting each perfect square j*j and take the minimum of dp[i - j*j] + 1. This is an unbounded knapSack DP where the items are perfect squares.
Edge cases include n = 0 (return 0), n = 1 (return 1), n where n itself is a perfect square (return 1), and large values up to 10^4 where O(n*sqrt(n)) is acceptable.
The perfect squares problem is an unbounded knapSack DP where the items are square numbers (1, 4, 9, ...) and we want to minimize the count to reach target n. The initial value dp[i] = i represents the worst case of using i ones (1+1+...+1).
For each i, we try subtracting each perfect square j*j<= i and take the minimum of dp[i-j*j] + 1. The inner loop runs sqrt(i) times, giving O(n*sqrt(n)) overall. This is optimal for n up to 10^4 in typical constraints.
Example Input & Output
7 = 4+1+1+1 (4 squares).
1 = 1.
12 = 4+4+4 (3 squares).
Zero needs no squares.
13 = 9+4 (2 squares).
Algorithm Flow
Solution Approach
Find the minimum number of perfect square numbers that sum up to n. Use dynamic programming where dp[i] is the minimum squares for i. Initialize dp[0]=0 and all others to Infinity. For each i from 1 to n, try every square j*j <= i and take dp[i] = min(dp[i], dp[i - j*j] + 1).
The recurrence considers each perfect square as the last coin in an amount-i coin change problem. For each square, we add 1 to the optimal solution for the remainder. The minimum across all squares is stored in dp[i].
Time complexity is O(n * sqrt(n)), space complexity is O(n).
Best Answers
class Solution {
public int solution(int n) {
int[] dp=new int[n+1];
for (int i=0;i<=n;i++) dp[i]=i;
for (int i=1;i<=n;i++) {
for (int j=1;j*j<=i;j++) {
dp[i]=Math.min(dp[i],dp[i-j*j]+1);
}
}
return dp[n];
}
}Comments (0)
Join the Discussion
Share your thoughts, ask questions, or help others with this Challenge.
