其他分享
首页 > 其他分享> > Leetcode 447:Number of Boomerangs

Leetcode 447:Number of Boomerangs

作者:互联网

Leetcode 447:Number of Boomerangs

You are given n points in the plane that are all distinct, where points[i] = [xi, yi]. 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).

Return the number of boomerangs.

说人话:

给定平面上 n 对互不相同的点 points ,其中 points[i] = [xi, yi] 。回旋镖是由点 (i, j, k) 表示的元组 ,其中 i 和 j 之间的距离和 i 和 k 之间的距离相等(需要考虑元组的顺序)。

返回平面上所有回旋镖的数量。

几个要点:

示例:

image-20210205104319203

[法1] 暴力法

思路
代码
class Solution {
    public int numberOfBoomerangs(int[][] points) {

        int result = 0;

        //三层遍历
        for(int a=0;a<points.length;a++){
            for(int b=0;b<points.length;b++){
                for(int c=0;c<points.length;c++){
                    //A.B.C为三个不同的点
                    if( a!=b && a!=c && b!=c){
                        //A.B的距离
                        int distanceAB = 
                          (points[a][0]-points[b][0])*(points[a][0]-points[b][0])+ 
                          (points[a][1]-points[b][1])*(points[a][1]-points[b][1]);
                        //A.C的距离
                        int distanceAC = 
                          (points[a][0]-points[c][0])*(points[a][0]-points[c][0])+ 
                          (points[a][1]-points[c][1])*(points[a][1]-points[c][1]);
                        //距离相等则累加
                        if( distanceAB == distanceAC){
                            result++;
                        }
                    }

                }
            }
        }
        return result;
    }
}
提交结果
image-20210205111651794
代码分析
改进思路

因为 N 的级别为 500,所以我们可以接受 n2 的复杂度, n3 就太大了。我们需要想办法将时间复杂度降为 O(n2) 甚至更低。

[法2] 查找表灵活选择键值

思路

我们可以发现题目中 点 i 其实是一个枢纽,那么我们就可以对于每个 点 i,遍历其他剩余点到 点 i 的距离,然后看看相同距离的点有多少个,对这些相同距离的点进行排列组合 An2,就可以了。

整体思路如下:

代码
class Solution {
    public int numberOfBoomerangs(int[][] points) {

        int result = 0;

        //遍历每一个点 i
        for(int i=0;i<points.length;i++){

            Map<Integer,Integer> map = new HashMap<>();

            //以 i 作为枢纽
            for(int j=0;j<points.length;j++){
                //记录其他点到点 i 的距离
                if( i!=j ){
                    //距离的平方
                    int distance = 
                    (points[i][0]-points[j][0])*(points[i][0]-points[j][0]) + 
                    (points[i][1]-points[j][1])*(points[i][1]-points[j][1]);

                    //统计相同记录的点的个数
                    Integer count = map.get(distance);
                    if(count !=null && count>0){
                        count++;
                        map.put(distance,count);
                    }else{
                        map.put(distance,1);
                    }
                }
            }

            //对这些相同距离的点进行排列组合
            Set<Integer> keys = map.keySet();
            for(Integer key: keys){
                Integer count = map.get(key);
                if(count != null && count >= 2){
                    result += (count)*(count-1);
                }
            }
        }
        return result;
    }
}
提交结果
image-20210205113016913
代码分析
陷阱

本题中保证点的坐标在 [-10000,10000] 的范围内,所以算距离的时候不会发生整数溢出。如果没有这个条件的话,最好算距离的时候转为 long 或者 decimal 来进行计算,避免整数溢出。

标签:count,map,int,Boomerangs,复杂度,447,距离,points,Leetcode
来源: https://blog.51cto.com/u_15298624/3035441