633. 平方数之和
题目描述
给定一个非负整数 c
,你要判断是否存在两个整数 a
和 b
,使得 a2 + b2 = c
。
示例 1:
输入:c = 5 输出:true 解释:1 * 1 + 2 * 2 = 5
示例 2:
输入:c = 3 输出:false
提示:
0 <= c <= 231 - 1
解法
方法一:数学 + 双指针
我们可以使用双指针的方法来解决这个问题,定义两个指针 \(a\) 和 \(b\),分别指向 \(0\) 和 \(\sqrt{c}\)。在每一步中,我们会计算 \(s = a^2 + b^2\) 的值,然后比较 \(s\) 与 \(c\) 的大小。如果 \(s = c\),我们就找到了两个整数 \(a\) 和 \(b\),使得 \(a^2 + b^2 = c\)。如果 \(s < c\),我们将 \(a\) 的值增加 \(1\),如果 \(s > c\),我们将 \(b\) 的值减小 \(1\)。我们不断进行这个过程直到找到答案,或者 \(a\) 的值大于 \(b\) 的值,返回 false
。
时间复杂度 \(O(\sqrt{c})\),其中 \(c\) 是给定的非负整数。空间复杂度 \(O(1)\)。
1 2 3 4 5 6 7 8 9 10 11 12 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
方法二:数学
这个问题实际上是关于一个数能否表示为两个平方数之和的条件。这个定理可以追溯到费马(Fermat)和欧拉(Euler),它在数论中是一个经典结果。
具体来说,这个定理可以表述为:
一个正整数 \( n \) 能表示为两个平方数之和的充要条件是:\( n \) 的所有形如 \( 4k + 3 \) 的素数因子的幂次均为偶数。
这意味着,如果我们将 \(n\) 分解成素数因子乘积的形式,即 \(n = p_1^{e_1} p_2^{e_2} \cdots p_k^{e_k}\),其中 \(p_i\) 是素数且 \(e_i\) 是它们对应的幂次,那么 \(n\) 可以表示为两个平方数之和,当且仅当所有 \(4k + 3\) 形式的素数因子 \(p_i\) 的幂次 \(e_i\) 都是偶数。
更正式地,假设 \(p_i\) 是形如 \(4k + 3\) 的素数,则对于每一个这样的 \(p_i\),要求 \(e_i\) 是偶数。
例如:
- 数字 \(13\) 是素数,且 \(13 \equiv 1 \pmod{4}\),因此它可以表示为两个平方数之和,即 \(13 = 2^2 + 3^2\)。
- 数字 \(21\) 分解为 \(3 \times 7\),其中 \(3\) 和 \(7\) 都是形如 \(4k + 3\) 的素数因子,并且它们的幂次都是 \(1\)(奇数),因此 \(21\) 不能表示为两个平方数之和。
总结起来,这个定理在数论中非常重要,用于判断一个数是否可以表示为两个平方数之和。
时间复杂度 \(O(\sqrt{c})\),其中 \(c\) 是给定的非负整数。空间复杂度 \(O(1)\)。
1 2 3 4 5 6 7 8 9 10 11 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|