题目
思路
题目需要尝试搜索两个数,使其之和为c
, 首先我们需要确定搜索范围。要满足
a
2
+
b
2
=
c
a^2 + b ^2 = c
a2+b2=c,则必有
0
≤
a
≤
c
,
0
≤
b
≤
c
,
0 \le a \le \sqrt{c},\ 0 \le b\le \sqrt{c},
0≤a≤c, 0≤b≤c,
因此,搜索范围限制在
[
0
,
c
]
[0,\sqrt{c}]
[0,c]。
我们设正确结果位于 [ a , b ] [a,b] [a,b]中,初始化 a = 0 , b = c a=0,\ b=\sqrt{c} a=0, b=c,开始搜索。
如果
a
2
+
b
2
<
c
a^2 + b^2 < c
a2+b2<c,我们可以确定正确结果的范围在
[
a
+
1
,
b
]
[a+1, b]
[a+1,b];如果
a
2
+
b
2
>
c
a^2 + b^2 > c
a2+b2>c,我们可以确定正确结果的范围为
[
a
,
b
−
1
]
[a,b-1]
[a,b−1],直到找到正确结果则返回true
,如果搜索到区间大小为0(
a
>
b
a>b
a>b)则范围false
。
正确性证明:
当 a 2 + b 2 < c a^2 + b^2 < c a2+b2<c时,除了将 a a a减1还可以通过将 b b b加1来使得$a^2 + b^2 的 结 果 增 大 , 然 而 , 我 们 在 之 前 的 步 骤 中 已 经 确 定 了 正 确 答 案 位 于 的结果增大,然而,我们在之前的步骤中已经确定了正确答案位于 的结果增大,然而,我们在之前的步骤中已经确定了正确答案位于[a,b] , 所 以 无 需 尝 试 ,所以无需尝试 ,所以无需尝试b+1 , 因 此 正 确 结 果 必 定 位 于 ,因此正确结果必定位于 ,因此正确结果必定位于[a+1, b] 中 ; 对 于 中;对于 中;对于a^2 + b^2 > c$同理。
代码
class Solution {
public:
bool judgeSquareSum(int c) {
long a,b;
a = 0;
b = sqrt(c);
while( a <= b) {
long tmp = a * a + b * b;
if (tmp == c) {
return true;
} else if ( tmp > c) {
b--;
} else {
a++;
}
}return false;
}
};