633. Sum of Square Numbers
思路:
这样的题给的值都会很大,再平方大概率会超int,那么我们在声明变量时需要long变量。
同时应该把传入的c的大小降下来,因为大于根号c的数,是不可能被使用的,所以我们从0-根号c开始找。
因为是a2+b2=c,所以我们要两次循环0-c的数,但是直接两个for循环会导致超时。
那么我们就采用双指针,左右开始向中间靠近。
每次sum = left2+right2,如果sum==c就return true,sum<c就left++,让sum增大,sum>c就right--,让sum减小。
如果循环结束未返回true,那么return false即可。
class Solution {
public:
bool judgeSquareSum(int c) {
long right = sqrt(c),left=0;
while(left<=right){
long long sum = left*left+right*right;
if(sum==c) return true;
else if(sum<c)left++;
else if(sum>c) right--;
}
return false;
}
};
上述是双指针的方法
还可通过费马平方和的方法获得结果,学习一下质因数分解的方法。
那么费马平方和定理为:一个数的所有质因数,当满足4k+3形式的质因数的最大的让这个质因数<=c时的幂为偶数时,该数才能被两个数的平方和表示。
class Solution {
public:
bool judgeSquareSum(int c) {
for(int i=2;i*i<=c;++i){
if(c%i!=0) continue; //如果不是质因数就跳过
int exp=0; //计算幂
while(c%i==0){
c /= i;
exp++;
}
if(i%4==3&&exp %2 !=0) return false; //只要满足4k+3的质因数的幂不为偶数就return false;
}
return c%4!=3; //因为当为c本身作为质因数时,循环不会进入,所以需要单独判断。且本身的幂为1,如果存在就时false,不存在才为true;
}
};