给定平面上 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]]
解法1:
思路:最容易想到的一种,暴力枚举出复合条件的三个点,然后每一种方案有两点位置交换的情况,结果乘以2。(O(n^3))
代码实现:
class Solution {
public static int numberOfBoomerangs(int[][] points) {
int count=0;
for (int i=0;i<points.length;i++)
{
for (int j=i+1;j<points.length;j++)
{
for (int k=j+1;k<points.length;k++)
{
if (calculateLong(points[i][0],points[i][1],points[j][0],points[j][1])
==calculateLong(points[i][0],points[i][1],points[k][0],points[k][1])
||calculateLong(points[j][0],points[j][1],points[i][0],points[i][1])
==calculateLong(points[j][0],points[j][1],points[k][0],points[k][1])
||calculateLong(points[k][0],points[k][1],points[i][0],points[i][1])
==calculateLong(points[k][0],points[k][1],points[j][0],points[j][1])) {
count++;
}
}
}
}
return count*2;
}
//计算两点距离的平方的方法(开方涉及到浮点数比较)
public static int calculateLong(int x1,int y1,int x2,int y2)
{
return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);
}
}
解法2:
思路:遍历每一个点,计算该点与其他点之间的距离,构建HashMap,将距离作为键值,距离为该键值的点的个数作为映射的值。计算并记录可以形成回旋镖的点的方案(1+2+3+...+(相同距离点的个数-1)),最终方案数*2即为回旋镖数。
代码实现:
class Solution {
public static int numberOfBoomerangs(int[][] points) {
HashMap<Integer, Integer> hm = new HashMap<Integer, Integer>();
int res = 0; //记录结果
int dis = 0; //记录距离
int freq = 0;
int tempRes = 0; //记录点方案数
for(int i = 0; i < points.length; i++)
{
//初始化
tempRes = 0;
hm.clear();
for(int j = 0; j < points.length; j++)
{
//计算距离
dis = (points[i][0] - points[j][0]) * (points[i][0] - points[j][0])
+ (points[i][1] - points[j][1]) * (points[i][1] - points[j][1]);
if(dis != 0)//判断是否是其本身
{
if(hm.containsKey(dis))//如果有相同距离的点
{
freq = hm.get(dis);
tempRes += freq;
hm.put(dis, freq + 1); //相同距离的点数+1
}
else
hm.put(dis, 1);
}
}
res += tempRes * 2; //一种点方案,后两点可以交换位置,即为两种回旋镖
}
return res;
}
}