633. 平方数之和

633. 平方数之和

leetcode 633. 平方数之和


题目:633. 平方数之和

给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a^2 + b^2 = c。

示例1:

输入: 5
输出: True
解释: 1 * 1 + 2 * 2 = 5

示例2:

输入: 3
输出: False

方法一:双指针(对撞指针)

思路:由题意可得a^2、b^2的最小值为0,最大值不能大于c。由于是平方和,且只需判断是否存在,因此负整数对结果没影响 ;由于负整数的平方值跟他对应的正整数的平方值相等,所以只需考虑非负整数即可;综上所述,可使用双指针一个指针指向值较小的元素,一个指针指向值较大的元素。指向较小元素的指针从头向尾遍历,指向较大元素的指针从尾向头遍历。

运行数据:执行用时:2 ms,内存消耗:36.2 MB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// LeetCode指定调用方法
public boolean judgeSquareSum(int c) {

// i标识头指针位置,j标识尾指针位置,通过sqrt确定尾指针最大值,在确定头指针最小值
int i = 0, j = (int)Math.sqrt(c), sum = 0;
i = (int)Math.sqrt(c - j * j);

// 双指针(对撞指针)算法
while (i <= j) {
sum = i * i + j * j;
if (sum == c) {
return true;
}else if (sum < c) {
i++;
} else {
j--;
}
}

return false;
}

方法二:直接使用sqrt

思路:直接使用sqrt函数确定a的最大值,并对其进行枚举,通过b^2=c-a^2得出b平方的值,最后通过sqrt判断b平方开方取整是否等于b。

运行数据:执行用时:4 ms,内存消耗:36.4 MB

1
2
3
4
5
6
7
8
9
10
11
12
// LeetCode指定调用方法
public boolean judgeSquareSum(int c) {

for (long a = 0; a * a <= c; a++) {
double b = Math.sqrt(c - a * a);
if (b == (int) b) {
return true;
}
}

return false;
}

方法三:费马平方和定理

思路:根据费马平方和定理得出的:一个非负整数 c 能够表示为两个整数的平方和,当且仅当 c 的所有形如 4k+3 的质因子的幂次均为偶数。证明方法可以见 这里

运行数据:执行用时:0 ms,内存消耗:36 MB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// LeetCode指定调用方法
public boolean judgeSquareSum(int c) {

// 判断因子c是否满足条件,因为c是c自己的因数,幂次是奇数(幂次只能为1),若C为4k+3的形式,将不满足推论
if ((c & 3) == 3) {
return false;
}

// 判断在2到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 & 3) == 3 && count % 2 != 0){
return false;
}
}
}

// 判断1和在c开平方到c之间的因子是否满足条件
return (c & 3) != 3;
}

相关链接:

学习所得,资料、图片部分来源于网络,如有侵权,请联系本人删除。

才疏学浅,若有错误或不当之处,可批评指正,还请见谅!


Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×