LeetCode刷题02 --633平方数之和
题目描述:给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
- 暴力解法(超时,我只能想到这个…)
class Solution {
public boolean judgeSquareSum(int c) {
int a=0,b=0;
while(b*b<=c){
a=b;
while(a*a<=c){ //刚开始居然还是用的a<c,愚蠢
if(a*a+b*b==c){
return true;
}
a++;
}
b++;
}
return false;
}
}
- 二分法
先固定a
然后在a至c-a^2中,进行二分查找b,注意这里找的是mid的平方
class Solution {
public boolean judgeSquareSum(int c) {
long a=0;
for(;a*a<=c;a++){
int b=c-(int)(a*a);
if(binarySearch(0,b,b)){
return true;
}
}
return false;
}
public boolean binarySearch(long low,long high,int target){
long mid=low+(high-low)/2;
while(low<=high){
if(mid*mid==target){
return true;
}else if(mid*mid>target){
return binarySearch(0,mid-1,target);
}else{
return binarySearch(mid+1,high,target);
}
}
return false;
}
}
这里还必须用递归,不然也超时,为什么用long定义a,b,mid,是因为int会出现溢出(int 果然不行)。
3.利用sqrt函数,开平方
class Solution {
public boolean judgeSquareSum(int c) {
long a=0;
while(a*a<=c){
double b=Math.sqrt(c-a*a);
if(b==(int)b){
return true;
}
a++;
}
return false;
}
}
4.费马平方和定理
一个非负整数 c 能够表示为两个整数的平方和,当且仅当 c 的所有形如 4k+3的质因子的幂次均为偶数。
我的理解:所有的满足4k+3的质因子的幂次都是偶数,才有这么个c
public class Solution {
public boolean judgeSquareSum(int c) {
for (int i = 2; i * i <= c; i++) {
int count = 0;
if (c % i == 0) {
while (c % i == 0) {
count++;
c /= i;
}
if (i % 4 == 3 && count % 2 != 0)
return false;
}
}
return c % 4 != 3;
}
}
5.看一下大神的代码
public boolean judgeSquareSum(int target) {
if (target < 0) return false;
int i = 0, j = (int) Math.sqrt(target);
while (i <= j) {
int powSum = i * i + j * j;
if (powSum == target) {
return true;
} else if (powSum > target) {
j--;
} else {
i++;
}
}
return false;
}
这也是双指针,不同的是,里面找的是两个数,i和j,而上面的二分法,找的是一个数,b。
厉害之处就在于右指针的选择,选的是 sqrt(target)。