您好,登录后才能下订单哦!
# LeetCode如何求平方数之和
## 问题描述
在LeetCode中,平方数之和问题(编号633)的题目要求如下:
> 给定一个非负整数 `c`,判断是否存在两个整数 `a` 和 `b`,使得 `a² + b² = c`。如果存在则返回 `true`,否则返回 `false`。
**示例:**
- 输入:`c = 5`
输出:`true`
解释:`1² + 2² = 5`
- 输入:`c = 3`
输出:`false`
解释:无法找到满足条件的整数组合
## 解题思路
### 方法一:暴力枚举(不推荐)
最直观的方法是双重循环枚举所有可能的 `a` 和 `b`,检查是否满足条件。但这种方法的时间复杂度为 `O(c)`,效率较低,不适用于大数。
```python
def judgeSquareSum(c: int) -> bool:
for a in range(int(c ** 0.5) + 1):
for b in range(int(c ** 0.5) + 1):
if a * a + b * b == c:
return True
return False
观察到 a
和 b
的取值范围为 [0, sqrt(c)]
,可以固定 a
,计算 b = sqrt(c - a²)
,然后检查 b
是否为整数。
import math
def judgeSquareSum(c: int) -> bool:
for a in range(int(math.sqrt(c)) + 1):
b = math.sqrt(c - a * a)
if b == int(b):
return True
return False
时间复杂度:O(sqrt(c))
空间复杂度:O(1)
利用双指针从两端向中间逼近:
1. 初始化 left = 0
,right = int(sqrt(c))
。
2. 计算 sum = left² + right²
:
- 若 sum == c
,返回 true
;
- 若 sum < c
,增加 left
;
- 若 sum > c
,减少 right
。
3. 当 left > right
时终止。
import math
def judgeSquareSum(c: int) -> bool:
left, right = 0, int(math.sqrt(c))
while left <= right:
current_sum = left * left + right * right
if current_sum == c:
return True
elif current_sum < c:
left += 1
else:
right -= 1
return False
时间复杂度:O(sqrt(c))
空间复杂度:O(1)
费马平方和定理指出:
一个自然数
c
可以表示为两个平方数之和,当且仅当在c
的质因数分解中,所有形如4k+3
的质因数的幂均为偶数。
利用该定理可以进一步优化:
1. 对 c
进行质因数分解。
2. 检查所有 4k+3
形式的质因数的幂是否为偶数。
import math
def judgeSquareSum(c: int) -> bool:
for i in range(2, int(math.sqrt(c)) + 1):
if c % i == 0:
count = 0
while c % i == 0:
count += 1
c //= i
if i % 4 == 3 and count % 2 != 0:
return False
return c % 4 != 3
时间复杂度:O(sqrt(c))
(质因数分解耗时)
空间复杂度:O(1)
方法 | 时间复杂度 | 适用场景 |
---|---|---|
暴力枚举 | O© | 仅适用于小规模数据 |
单指针优化 | O(sqrt©) | 通用,但仍有优化空间 |
双指针法 | O(sqrt©) | 最优解,推荐使用 |
数学法 | O(sqrt©) | 理论最优,实现较复杂 |
0 = 0² + 0²
,应返回 true
。c
接近 2^31 - 1
时,需注意整数溢出问题(Python无需担心)。c
为非负整数,无需处理。平方数之和问题可以通过多种方法解决,其中双指针法在时间复杂度和代码可读性上达到了较好的平衡。对于追求极致性能的场景,可考虑费马平方和定理的数学解法。在实际面试或竞赛中,推荐优先实现双指针法。
提示:LeetCode上的类似问题还包括「有效的完全平方数」(367题),可结合学习。 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。