Loading

力扣 - 447. 回旋镖的数量

题目

447. 回旋镖的数量

思路1(暴力,不推荐)

  • 暴力三层循环,搜索所有的结果
  • 超时,不推荐

代码

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        int res = 0;
        for (int i = 0; i < points.length; i++) {
            for (int j = 0; j < points.length; j++) {
                for (int k = 0; k < points.length; k++) {
                    if (i != j && i != k && j != k) {
                        int d1 = dis(points[i], points[j]);
                        int d2 = dis(points[i], points[k]);
                        if (d1 == d2) {
                            res++;
                        }
                    }
                }
            }
        }
        return res;
    }

    public int dis(int[] point1, int[] point2) {
        // 计算两点的距离
        return (int) (Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
    }
}

复杂度分析

  • 时间复杂度:\(O(N^3)\),暴力3层循环,其中 N 表示数组的长度
  • 空间复杂度:\(O(1)\)

思路2(哈希表)

  • 外层for遍历一遍数组,计算其他点与它的距离
  • 每次计算一个点的其他的与它距离时,使用一个新的哈希表,key存储的是他们未开根号的距离,value是存储出现的次数
  • 如果value值是1,代表只出现一次
  • 如果value值是2,说明刚刚好有两个相等的点,但是排列的方式有两种,如果值为3,排列的方式有6种。即有 n个相同的点,排列方式有n(n-1)

代码

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        int res = 0;

        for (int i = 0; i < points.length; i++) {
            // 计算每个点时使用一个新的哈希表
            Map<Integer, Integer> hashtable = new HashMap<>();
            for (int j = 0; j < points.length; j++) {
                // i != j,因为计算的是其他的点
                if (i != j) {
                    // 获取未开根号的距离
                    int d = dis(points[i], points[j]);
                    hashtable.put(d, hashtable.getOrDefault(d, 0) + 1);
                }
            }

            for (Map.Entry<Integer, Integer> entry : hashtable.entrySet()) {
                // 因为只有距离相等才会被记录两次,如果没有和他相等的,只会被记录一次,那么我们就忽略
                if (entry.getValue() >= 2) {
                    res += entry.getValue()*(entry.getValue()-1);
                }
            }
        }
        return res;
    }

    public int dis(int[] point1, int[] point2) {
        // 计算两点的距离
        return (int) (Math.pow(point1[0] - point2[0], 2) + Math.pow(point1[1] - point2[1], 2));
    }
}

复杂度分析

  • 时间复杂度:\(O(N^2)\),其中 N 为数组的长度
  • 空间复杂度:\(O(N^2)\),其中 N 为哈希表的大小,需要使用N个哈希表记录N个点到其他N-1的距离出现的次数,最坏情况下每个距离都不一样,那么需要的每个哈希表大小为N-1
posted @ 2020-11-24 14:30  linzeliang  阅读(98)  评论(0)    收藏  举报