Medium
题目描述
给定平面上 n 个不同的点,其中 points[i] = [xi, yi]。回旋镖是由点 (i, j, k) 组成的元组,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(元组的顺序很重要)。
返回回旋镖的数量。
示例 1:
输入:points = [[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
示例 2:
输入:points = [[1,1],[2,2],[3,3]]
输出:2
示例 3:
输入:points = [[1,1]]
输出:0
提示:
n == points.length1 <= n <= 500points[i].length == 2-10^4 <= xi, yi <= 10^4- 所有点都是唯一的
解题思路
解题思路
这道题要求找到所有满足条件的回旋镖,即对于三个点 (i, j, k),点 i 到点 j 的距离等于点 i 到点 k 的距离。
核心思想:枚举中心点
对于每个点作为回旋镖的中心点 i,我们需要找到有多少对点 (j, k) 满足 distance(i,j) = distance(i,k)。
算法步骤:
- 遍历每个点作为中心点 i
- 对于当前中心点,计算它到其他所有点的距离
- 使用哈希表统计相同距离的点的个数
- 如果有 n 个点到中心点的距离相同,那么可以形成 n×(n-1) 个回旋镖(因为顺序重要)
距离计算优化:
为了避免浮点数精度问题,我们可以使用距离的平方来比较,即 (x1-x2)² + (y1-y2)²。
时间复杂度分析:
- 外层循环遍历 n 个点作为中心点:O(n)
- 内层循环计算到其他点的距离:O(n)
- 总时间复杂度:O(n²)
代码实现
class Solution {
public:
int numberOfBoomerangs(vector<vector<int>>& points) {
int result = 0;
for (int i = 0; i < points.size(); i++) {
unordered_map<int, int> distCount;
for (int j = 0; j < points.size(); j++) {
if (i == j) continue;
int dx = points[i][0] - points[j][0];
int dy = points[i][1] - points[j][1];
int distSquare = dx * dx + dy * dy;
distCount[distSquare]++;
}
for (auto& pair : distCount) {
int count = pair.second;
if (count >= 2) {
result += count * (count - 1);
}
}
}
return result;
}
};
class Solution:
def numberOfBoomerangs(self, points: List[List[int]]) -> int:
result = 0
for i in range(len(points)):
dist_count = {}
for j in range(len(points)):
if i == j:
continue
dx = points[i][0] - points[j][0]
dy = points[i][1] - points[j][1]
dist_square = dx * dx + dy * dy
dist_count[dist_square] = dist_count.get(dist_square, 0) + 1
for count in dist_count.values():
if count >= 2:
result += count * (count - 1)
return result
public class Solution {
public int NumberOfBoomerangs(int[][] points) {
int result = 0;
for (int i = 0; i < points.Length; i++) {
Dictionary<int, int> distCount = new Dictionary<int, int>();
for (int j = 0; j < points.Length; j++) {
if (i == j) continue;
int dx = points[i][0] - points[j][0];
int dy = points[i][1] - points[j][1];
int distSquare = dx * dx + dy * dy;
if (distCount.ContainsKey(distSquare)) {
distCount[distSquare]++;
} else {
distCount[distSquare] = 1;
}
}
foreach (var pair in distCount) {
int count = pair.Value;
if (count >= 2) {
result += count * (count - 1);
}
}
}
return result;
}
}
/**
* @param {number[][]} points
* @return {number}
*/
var numberOfBoomerangs = function(points) {
let count = 0;
for (let i = 0; i < points.length; i++) {
let distanceMap = new Map();
for (let j = 0; j < points.length; j++) {
if (i !== j) {
let dx = points[i][0] - points[j][0];
let dy = points[i][1] - points[j][1];
let distance = dx * dx + dy * dy;
distanceMap.set(distance, (distanceMap.get(distance) || 0) + 1);
}
}
for (let freq of distanceMap.values()) {
count += freq * (freq - 1);
}
}
return count;
};
复杂度分析
| 复杂度类型 | 复杂度 | 说明 |
|---|---|---|
| 时间复杂度 | O(n²) | 需要遍历每个点作为中心点,并计算到其他所有点的距离 |
| 空间复杂度 | O(n) | 哈希表最多存储 n-1 个不同的距离值 |
相关题目
- . Line Reflection (Medium)