447. Number of Boomerangs
Given n points in the plane that are all pairwise distinct, 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).
Find the number of boomerangs. You may assume that n will be at most 500 and coordinates of points are all in the range [-10000, 10000] (inclusive).
Example:
Input: [[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]]
解析:首先lc上这道题tag是easy,但博主真心觉得这道题并不easy,陷阱很多,需要些空间想象能力以及高中数学知识。题目意思是说给出平面中一些点,求两点连起来的两段相等的线段的可能性,其中两段线段要有一个公共顶点。需要注意的是要考虑顺序,比如ba = bc 和 bc = ba算两种可能性。先来看一个简单例子,假设有5个点距离a点距离都是2,那么从这五个点中选出到a的两条线段的可能性就是C(5,2)(高中数学组合数),再考虑顺序不同则要乘以2。所以到a点距离为2的可能性有C(5,2) * 2 = 5! / (2! * 3!) * 2 = 5 * 4种。同理对每一个点做如上计算,加和总数就是最后答案。
//Time: O(n2), Space: O(n) public int numberOfBoomerangs(int[][] points) { if (points == null || points.length == 0 || points[0].length == 0) { return 0; } int result = 0; for (int i = 0; i < points.length; i++) { HashMap<Integer, Integer> map = new HashMap<Integer, Integer>(); for (int j = 0; j < points.length; j++) { if (i == j) {//去掉自己和自己的距离的情况 continue; } int x = points[i][0] - points[j][0];//横坐标差 int y = points[i][1] - points[j][1];//纵坐标差 int dis = x * x + y * y; if (!map.containsKey(dis)) { map.put(dis, 1); } else { map.put(dis, map.get(dis) + 1); } } for (int v : map.values()) { result = result + v * (v - 1); //C(n, 2) * 2的结果 } } return result; }