参考代码:
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) {
if(n - i * i == 0) return 1;
}
for(int i = 0; i * i < n; ++i) {
for(int j = 0; j * j < n; ++j) {
if(n - i * i - j * j == 0) return 2;
}
}
return 3;
}
}
大致思路:
- 任何正整数都可以拆分成不超过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(摘自力扣caibirbme)
具体实现:
while(n % 4 == 0) n /= 4;
if(n % 8 == 7) return 4;
首先先除以4,直到不能再除为止,再对8求余等于7时才是符合 n = (4^a)*(8b+7),所以这是返回4。
for(int i = 0; i * i <= n; ++i) {
if(n - i * i == 0) return 1;
}
从0开始一个一个试,看是哪个数的平方,因此必须满足i*i<=n,当n - i * i == 0时则说明找到了那个值,并只有一个,所以返回1。
for(int i = 0; i * i < n; ++i) {
for(int j = 0; j * j < n; ++j) {
if(n - i * i - j * j == 0) return 2;
}
}
这个和判断1的很像,就是用两层for循环找到两个的平方和 等于n的数,如果满足则返回2。
最后只剩下等于3的情况,所以如果代码能走到最后只能是3。