447. 回旋镖的数量
难度中等
给定平面上 **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.length
1 <= n <= 500
points[i].length == 2
-104 <= xi, yi <= 104
- 所有点都 互不相同
思路:
由题可知, 找出回旋镖的数量, 就是需要找出以某个点为顶点, 在点集合中找出符合两个点距离顶点距离相等
直接使用暴力破解法, 遍历点集合, 求出其他点距离当前点的距离, 用哈希表来存储距离节点的距离和对应的节点个数, 最后再遍历value, 求解即可
代码如下
public int numberOfBoomerangs(int[][] points) {
int res = 0;
int n = points.length;
for (int i = 0; i < n; i++) {
// key为距离, value是离当前点的距离为key的点 个数
Map<Integer, Integer> instanceMap = new HashMap<>();
for (int j = 0; j < n; ++j) {
if (j == i) continue;
int instance = (int) (Math.pow(points[j][0] - points[i][0], 2) + Math.pow(points[j][1] - points[i][1], 2));
instanceMap.put(instance, instanceMap.getOrDefault(instance, 0) + 1);
}
for (int count : instanceMap.values()) {
// 如果节点个数小于1, 则表示当前距离只有 小于或等于1个的节点
if (count <= 1) continue;
/*
当前距离个数大于等于2, 那么符合可以组成回旋表的组合个数就是 (1+2+3+..+n) * 2
乘 2 是因为回旋镖两个点的顺序可以调换
所以个数就是 n * (n - 1)
*/
res += count * (count - 1);
}
}
return res;
}
@Test
public void numberOfBoomerangsTest() {
int[][] points = new int[][]{new int[]{0,0}, new int[]{1,0}, new int[]{2,0}};
int res = numberOfBoomerangs(points);
assert res == 2;
}