从0开始的秋招刷题路,记录下所刷每道题的题解,帮助自己回顾总结
633. 平方数之和
给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a 2 + b 2 = c a^2 + b^2 = c a2+b2=c 。
示例 1:
输入:c = 5
输出:true
解释:1 * 1 + 2 * 2 = 5
示例 2:
输入:c = 3
输出:false
提示:
0 <= c <=
2
31
−
1
2^{31} - 1
231−1
基本分析
根据等式
a
2
+
b
2
=
c
a^2 + b^2 = c
a2+b2=c,可得知 a 和 b 的范围均为
[
0
,
c
]
[0,\sqrt{c}]
[0,c]
基于此我们会有以下几种做法。
枚举
我们可以枚举 a ,边枚举边检查是否存在 b 使得等式成立。
这样做的复杂度为 O ( c ) O(\sqrt{c}) O(c)
class Solution {
public boolean judgeSquareSum(int c) {
int max = (int)Math.sqrt(c);
for (int a = 0; a <= max; a++) {
int b = (int)Math.sqrt(c - a * a);
if (a * a + b * b == c) return true;
}
return false;
}
}
时间复杂度:
O
(
c
)
O(\sqrt{c})
O(c)
空间复杂度:
O
(
1
)
O(1)
O(1)
双指针
由于 a 和 b 的范围均为
[
0
,
c
]
[0,\sqrt{c}]
[0,c],因此我们可以使用「双指针」在
[
0
,
c
]
[0,\sqrt{c}]
[0,c]范围进行扫描:
a
2
+
b
2
=
=
c
a^2 + b^2 == c
a2+b2==c : 找到符合条件的 a 和 b,返回 true
a
2
+
b
2
<
c
a^2 + b^2 < c
a2+b2<c: 当前值比目标值要小,a++
a
2
+
b
2
>
c
a^2 + b^2 > c
a2+b2>c: 当前值比目标值要大,b–
class Solution {
public boolean judgeSquareSum(int c) {
long a = 0, b = (long) Math.sqrt(c);
while (a <= b) {
long cur = a * a + b * b;
if (cur == c) {
return true;
} else if (cur > c) {
b--;
} else {
a++;
}
}
return false;
}
}
时间复杂度:
O
(
c
)
O(\sqrt{c})
O(c)
空间复杂度:
O
(
1
)
O(1)
O(1)
费马平方和
费马平方和 : 奇质数能表示为两个平方数之和的充分必要条件是该质数被 4 除余 1 。
翻译过来就是:当且仅当一个自然数的质因数分解中,满足 4k+3 形式的质数次方数均为偶数时,该自然数才能被表示为两个平方数之和。
因此我们对 c 进行质因数分解,再判断满足 4k+3 形式的质因子的次方数是否均为偶数即可。
代码:
public class Solution {
public boolean judgeSquareSum(int c) {
for (int i = 2, cnt = 0; i * i <= c; i++, cnt = 0) {
while (c % i == 0 && ++cnt > 0) c /= i;
if (i % 4 == 3 && cnt % 2 != 0) return false;
}
return c % 4 != 3;
}
}
时间复杂度:
O
(
c
)
O(\sqrt{c})
O(c)
空间复杂度:
O
(
1
)
O(1)
O(1)