633. 平方数之和
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。
示例 1:
输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5
示例 2:
输入:c = 3
输出:false
示例 3:
输入:c = 4
输出:true
示例 4:
输入:c = 2
输出:true
示例 5:
输入:c = 1
输出:true
提示:
0 <= c <= 2^31 - 1
题解:
首先最直白的便是直接暴力。但会超时。
代码:
bool judgeSquareSum(int c){
for(long i=0;i*i<=c;i++)
{
for(long j=0;j*j<=c;j++)
{
if(i*i+j*j==c)
{
return 1;
}
}
}
return 0;
}
接着会想到可以减少一个for,即使用c来配合a直接找出b,然后判断一下你找出的满足a^2 + b^2 = c 的b是否满足是整数即可。
代码:
bool judgeSquareSum(int c){
for(long i=0;i*i<=c;i++)
{
long j = (long)pow(c-i*i,0.5);
double j1 = pow(c-i*i,0.5);
if(j1==(double)j)
{
return 1;
}
}
return 0;
}
接着想到可以使用双指针进行查找。
即对于a方 + b方 = c
若直接等于则输出true即可;
若小于c,则位于a的指针 + 1即可;
若大于c,则位于b的指针 - 1即可。
为什么呢?难道小于c时我们不能让b的指针 + 1 吗?大于c时我们不能让a的指针 - 1 吗?
我们可以模拟一下什么时候可能这种查找会失效。
证明:
代码:
bool judgeSquareSum(int c){
int i = 0;
int j = sqrt(c);
while(i<=j)
{
if(i*i==c - j*j) //为了避免因为越界而使用long,于是使用减法来规避
{
return 1;
}
else if(i*i>c - j*j)
{
j--;
}
else
{
i++;
}
}
return 0;
}
java版本:
class Solution {
public boolean judgeSquareSum(int c) {
int i = 0;
int j = (int)Math.sqrt(c);
while(i<=j)
{
if(i*i==c - j*j)
{
return true;
}
else if(i*i>c - j*j)
{
j--;
}
else
{
i++;
}
}
return false;
}
}
C++
class Solution {
public:
bool judgeSquareSum(int c) {
int i = 0;
int j = sqrt(c);
while(i<=j)
{
if(i*i==c - j*j)
{
return true;
}
else if(i*i>c - j*j)
{
j--;
}
else
{
i++;
}
}
return false;
}
};