原题目:https://leetcode-cn.com/problems/perfect-squares/
思路一:
进行广度优先遍历,先创建完全平方数数组sq,对于一层中的元素依次和数组sq的元素进行比较。
1、如果元素等于sq的元素:说明找到了答案
2、如果元素小于sq的元素,跳过
3、如果元素大于sq的元素,相减进入队列。
为了避免重复元素节省时间,可以用set代替queue。
代码:
class Solution {
public:
int numSquares(int n) {
vector<int> sq;
for(int i=1;i*i<=n;i++){
sq.push_back(i*i);
}
set<int> queue;
queue.insert(n);
int level = 0;
while(queue.size()){
level ++;
set<int> next_queue;
for(int i:queue){
for(int j:sq){
//遇到了完全平方数,找到了答案
if(i==j) return level;
else if(i<j) break;
else next_queue.insert(i-j);
}
}
queue = next_queue;
}
return level;
}
};
思路二:
- 任何正整数都可以拆分成不超过4个数的平方和 ---> 答案只可能是1,2,3,4
- 如果一个数最少可以拆成4个数的平方和,则这个数还满足 n = (4^a)*(8b+7) ---> 因此可以先看这个数是否满足上述公式,如果不满足,答案就是1,2,3了
- 如果这个数本来就是某个数的平方,那么答案就是1,否则答案就只剩2,3了
- 如果答案是2,即n=a^2+b^2,那么我们可以枚举a,来验证,如果验证通过则答案是2
- 只能是3
代码:
class Solution {
public:
int numSquares(int n) {
while(n%4==0) n /= 4;
if(n%8==7) return 4;
for(int i=0;i*i<n;i++){
int j = pow(n-i*i,0.5);
if(n==i*i+j*j) return !!i+!!j;
}
return 3;
}
};