Easy
题目描述
平方和三元组 (a,b,c) 是指满足 a² + b² = c² 的三个整数。
给定一个整数 n,返回满足 1 <= a, b, c <= n 的平方和三元组的数量。
示例 1:
输入:n = 5
输出:2
解释:平方和三元组有 (3,4,5) 和 (4,3,5)。
示例 2:
输入:n = 10
输出:4
解释:平方和三元组有 (3,4,5), (4,3,5), (6,8,10), 和 (8,6,10)。
约束条件:
- 1 <= n <= 250
提示:
- 遍历所有可能的 (a,b) 对,检查 a² + b² 的平方根是否为不超过 n 的整数
- 可以使用二分查找或内置的 sqrt 函数来检查一个数的平方根是否为整数
解题思路
解题思路
这是一道寻找勾股数(毕达哥拉斯三元组)的问题。我们需要找到满足 a² + b² = c² 且 1 ≤ a, b, c ≤ n 的所有三元组。
方法一:暴力枚举(推荐)
最直观的方法是枚举所有可能的 a 和 b 值,然后计算 c = √(a² + b²),检查 c 是否为整数且在范围内。
具体步骤:
- 遍历 a 从 1 到 n
- 遍历 b 从 1 到 n
- 计算 c² = a² + b²
- 检查 c 是否为完全平方数且 c ≤ n
- 如果满足条件,计数器加 1
时间复杂度为 O(n²),由于 n ≤ 250,这个复杂度完全可以接受。
方法二:优化枚举
可以通过一些数学性质来优化,比如当 a > b 时,如果 (b,a,c) 已经被计算过,就不需要重复计算 (a,b,c)。但考虑到题目要求统计所有三元组(包括 (3,4,5) 和 (4,3,5) 这样的不同排列),暴力方法更直接。
判断完全平方数可以使用整数平方根函数,然后验证平方根的平方是否等于原数。
代码实现
class Solution {
public:
int countTriples(int n) {
int count = 0;
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= n; b++) {
int c_squared = a * a + b * b;
int c = sqrt(c_squared);
if (c * c == c_squared && c <= n) {
count++;
}
}
}
return count;
}
};
class Solution:
def countTriples(self, n: int) -> int:
count = 0
for a in range(1, n + 1):
for b in range(1, n + 1):
c_squared = a * a + b * b
c = int(c_squared ** 0.5)
if c * c == c_squared and c <= n:
count += 1
return count
public class Solution {
public int CountTriples(int n) {
int count = 0;
for (int a = 1; a <= n; a++) {
for (int b = 1; b <= n; b++) {
int cSquared = a * a + b * b;
int c = (int)Math.Sqrt(cSquared);
if (c * c == cSquared && c <= n) {
count++;
}
}
}
return count;
}
}
/**
* @param {number} n
* @return {number}
*/
var countTriples = function(n) {
let count = 0;
for (let a = 1; a <= n; a++) {
for (let b = 1; b <= n; b++) {
let cSquared = a * a + b * b;
let c = Math.sqrt(cSquared);
if (c === Math.floor(c) && c <= n) {
count++;
}
}
}
return count;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n²) | 需要遍历所有可能的 (a,b) 对 |
| 空间复杂度 | O(1) | 只使用常量额外空间 |