【LeetCode】回旋镖的数量

给定平面上 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;
    }

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值