447. 回旋镖的数量
447. 回旋镖的数量
题目
You are given n points in the plane that are all distinct , where points[i] = [xi, yi]. A boomerang is a tuple of points (i, j, k) such that the distance between i and j equals the distance between i and k(the order of the tuple matters).
Return the number of boomerangs.
Example 1:
Input: points = [[0,0],[1,0],[2,0]]
Output: 2
Explanation: The two boomerangs are [[1,0],[0,0],[2,0]] and [[1,0],[2,0],[0,0]].
Example 2:
Input: points = [[1,1],[2,2],[3,3]]
Output: 2
Example 3:
Input: points = [[1,1]]
Output: 0
Constraints:
n == points.length1 <= n <= 500points[i].length == 2-10^4 <= xi, yi <= 10^4- All the points are unique.
题目大意
给定平面上 n 对 互不相同 的点 points ,其中 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)的 回旋镖(Boomerang),即满足:dist(i, j) == dist(i, k)其中dist(i, j)表示点i和j之间的距离。
- 题目要求找到所有满足
计算点对之间的距离
- 我们可以使用 平方欧几里得距离 来避免浮点运算:
dist(i, j) = (x1 - x2)^2 + (y1 - y2)^2 - 对于每个点
i,统计它与其他点的距离出现的次数。
- 我们可以使用 平方欧几里得距离 来避免浮点运算:
利用哈希表统计相同距离的点
- 对于每个点
i,用哈希表count统计到其他点的距离:count[dist]记录当前i点下,出现相同dist的点的个数。
- 若
count[dist] = m,那么从这些点中选出两个点(j, k)组成回旋镖的方案数为:m * (m - 1)因为j -> k和k -> j是不同的排列。
- 对于每个点
遍历所有点,累加所有方案
- 对于每个点
i,遍历j计算所有dist(i, j)并更新count[dist]统计数量。 - 计算
m * (m - 1)并累加到res。
- 对于每个点
复杂度分析
- 时间复杂度:
O(n^2)- 两层循环计算所有点对的距离,共
O(n^2)次。 count哈希表的插入和查询平均时间复杂度为O(1),整体O(n^2)。
- 两层循环计算所有点对的距离,共
- 空间复杂度:
O(n)count哈希表最多存储n个不同的距离(极端情况)。- 由于
count每轮i计算完成后都会清空,额外空间复杂度为O(n)。
代码
/**
* @param {number[][]} points
* @return {number}
*/
var numberOfBoomerangs = function (points) {
const n = points.length;
let res = 0;
for (let i = 0; i < n; i++) {
let count = new Map();
for (let j = 0; j < n; j++) {
if (i === j) continue;
const [x1, y1] = points[i];
const [x2, y2] = points[j];
const dist = (x1 - x2) ** 2 + (y1 - y2) ** 2;
const cnt = count.get(dist) || 0;
res += 2 * cnt; // 两个排列: (j, k) 和 (k, j)
count.set(dist, cnt + 1);
}
}
return res;
};
相关题目
| 题号 | 标题 | 题解 | 标签 | 难度 | 力扣 |
|---|---|---|---|---|---|
| 356 | 直线镜像 🔒 | 数组 哈希表 数学 | 🟠 | 🀄️ 🔗 |
