public int numSquares(int n) {
if (n < 2) {
return 1;
}
// find all the squres smaller than n
ArrayList<Integer> squares = new ArrayList<>();
int s = 1;
while (s * s <= n) {
squares.add(s * s);
s++;
}
// backpack, item = all the squares, value = 0 to n
int[][] dp = new int[squares.size() + 1][n + 1];
// init first row to MAX, because you need to put infinite among of 0 item in to fill the bag
for (int i = 0; i <= n; i++) {
dp[0][i] = Integer.MAX_VALUE;
}
for (int i = 1; i <= squares.size(); i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][j];
if (j >= squares.get(i - 1)) {
dp[i][j] = Math.min(dp[i][j], dp[i][j - squares.get(i - 1)] + 1);
}
}
}
return dp[squares.size()][n];
}
public int numSquares(int n) {
if (n < 0) {
return -1;
}
List<Integer> squares = new ArrayList<>();
int s = 1;
while (s * s <= n) {
squares.add(s * s);
s++;
}
Queue<Integer> queue = new LinkedList<>();
queue.offer(n);
int step = 0;
while (!queue.isEmpty()) {
step++;
int size = queue.size();
for (int i = 0; i < size; i++) {
int cur = queue.poll();
for (int j = 0; j < squares.size(); j++) {
int nei = squares.get(j);
int diff = cur - nei;
if (diff == 0) {
return step;
} else if (diff > 0) {
queue.offer(diff);
} else {
break;
}
}
}
}
return -1;
}