给定平面上 n 对不同的点,“回旋镖” 是由点表示的元组 (i, j, k)
,其中 i
和 j
之间的距离和 i
和 k
之间的距离相等(需要考虑元组的顺序)。
找到所有回旋镖的数量。你可以假设 n 最大为 500,所有点的坐标在闭区间 [-10000, 10000] 中。
示例:
输入:[[0,0],[1,0],[2,0]]
输出:2
解释:两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]
答案:
1public int numberOfBoomerangs(int[][] points) {
2 int res = 0;
3 Map<Integer, Integer> map = new HashMap<>();
4 for (int i = 0; i < points.length; i++) {
5 for (int j = 0; j < points.length; j++) {
6 if (i == j)
7 continue;
8 int d = getDistance(points[i], points[j]);
9 map.put(d, map.getOrDefault(d, 0) + 1);
10 }
11 for (int val : map.values()) {
12 res += val * (val - 1);
13 }
14 map.clear();
15 }
16 return res;
17}
18
19private int getDistance(int[] a, int[] b) {
20 int dx = a[0] - b[0];
21 int dy = a[1] - b[1];
22 return dx * dx + dy * dy;
23}
解析:
这题的意思是平面上有n个点,随便找3个点(i,j,k)并且i到j的距离和i到k的距离相等。找出这样的3个点共有多少个。getDistance是求两点之间的距离的平方,这里没有开根号。上面题不太好理解的估计是res += val * (val - 1);这样一行代码。这行代码是放在第一个for循环中的,举个例子,比如第一次循环的时候,拿第一个点A和后面的所有点比较并计算距离,如果val等于1,说明到A点距离为val的只有1个,构不成回旋镖,所以val * (val - 1)等于0。如果val等于2的时候,说明有2个点到点A的距离相等,所以可以构成一个回旋镖,但因为有顺序的,可以调换位置,所以有两个。同样如果val为3的时候,可以构成3组,但每组又可以调换位置,所以有6个……。再来改一下
1public int numberOfBoomerangs(int[][] points) {
2 int result = 0;
3 HashMap<Integer, Integer> distMap = new HashMap<>();
4 for (int[] i : points) {
5 for (int[] j : points) {
6 if (i == j) continue;
7 int dist = getDis(i, j);
8 int prevDist = distMap.getOrDefault(dist, 0);
9 distMap.put(dist, prevDist + 1);
10 result += prevDist << 1;
11 }
12 distMap.clear();
13 }
14 return result;
15}
16
17public int getDis(int[] p, int[] q) {
18 int a = p[0] - q[0];
19 int b = p[1] - q[1];
20 return a * a + b * b;
21}