LeetCode 447. 回旋镖的数量

236 阅读1分钟

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;
}