1.题目
解法:(BFS队列实现)
这种题目特点就是:你同时有好多的选项可以选择。
思想就是:列举出所有可能组成该数的完全平方数,那么一个点就对应arr.size()的选择,使用队列记录每次减之后的结果,使用count记录减的次数,寻找第一个减为0的数。
class oneVal{
int res = 0;
int count = 0;
public oneVal(int r, int c){
res = r;
count = c;
}
}
class Solution {
public int numSquares(int n) {
int res = 0;
oneVal tmp = null;
ArrayList<Integer> arr = new ArrayList<>();
int i = 1;
while(i * i <= n){
arr.add(i*i);
++i;
}
Queue<oneVal> queue = new LinkedList<oneVal>();
queue.offer(new oneVal(n, 0));
while(!queue.isEmpty()){
tmp = queue.poll();
for(i = arr.size()-1; i >= 0; i--){
res = tmp.res - arr.get(i);
if(res > 0){
queue.offer(new oneVal(res, tmp.count+1));
}else if(res == 0){
return tmp.count+1;
}else{
continue;
}
}
}
return -1;
}
}
(1)一次性将所有的余数 对应 这个平方数,这样的话,每次level就可以统一计算。
(2)余数如果小于了平方数,那么就是不合理的,因为我要找到比我小的完全平方数。
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
class Solution {
public int numSquares(int n) {
ArrayList<Integer> square_nums = new ArrayList<>();
for (int i = 1; i * i <= n; ++i) {
square_nums.add(i * i);
}
Set<Integer> queue = new HashSet<Integer>();
queue.add(n);
int level = 0;
while (queue.size() > 0) {
level += 1;
Set<Integer> next_queue = new HashSet<Integer>();
// 从队列出来的每一个数都会和完全平方数进行比对,所以只要相等,那就结束
for (Integer remainder : queue) {
for (Integer square : square_nums) {
// 因为Integer类,所以判断内容相等用equals
if (remainder.equals(square)) {
return level;
// 都比余数大了,那后面的数,就没必要比了(从小到大)
} else if (remainder < square) {
break;
} else {
// 因为得到的余数和原来的不一样,所以就使用了新的quque
next_queue.add(remainder - square);
}
}
}
queue = next_queue;
}
return level;
}
}