LeetCode447. 回旋镖的数量

一、题目描述

☆☆☆☆☆二、解法

思路:暴力解法是O(n^3)

观察到 i 是一个“枢纽”,对于每个点 i ,遍历其余的点到 i 的距离。  时间复杂度O(n^2),空间复杂度O(n)

使用Map,其键是距离,值是距离出现的频次。 例如,如果距离值 dis 对应的频次为1,那就无法找到两个点与 i 距离dis相等。

Note:由于把距离作为键,而计算距离开根号会出现浮点数,因此,可以用距离的平方代替。

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        if (points == null || points.length < 3) return 0;
        /**
         *  写法1
         */
        /*
        int count = 0;
        Map<Integer,Integer> map = new HashMap<>();  // key/value => 距离/出现次数
        for (int i = 0; i < points.length; i++) {  // 每一个 i 都是一个枢纽点
            for (int j = 0; j < points.length; j++) {
                if (j != i) {
                    map.put(dis(points,i,j), map.getOrDefault(dis(points,i,j), 0) + 1);
                }
            }
            for (int d : map.keySet()) {
                if (map.get(d) > 1) {
                    count += map.get(d) * (map.get(d) - 1);
                }
            }
            map.clear();
        }
        return count;
        */
        /**
         *  写法2:对上述代码进行优化
         *   优化思路为:假设当前同一距离的数量为 n, 回旋镖数量为 n*(n-1),
         *              当再出现一个同一距离时,回旋镖的数量应为 (n+1)*n,
         *              与之前相差 (n+1)*n - n*(n-1) = 2*n,
         *              所以只需要把最后答案加上 2*n, 最后 n+1 再存储到哈希表中。
         */
        int count = 0;
        Map<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < points.length; i++) {
            for (int j = 0; j < points.length; j++) {
                if (i != j) {
                    int d = dis(points, i, j);
                    if (!map.containsKey(d)) {
                        map.put(d, 1);
                    }else {
                        int n = map.get(d);
                        count += 2*n;
                        map.put(d, n+1);
                    }
                }
            }
            map.clear();
        }
        return count;
    }
    // 计算两点距离的平方
    private int dis(int[][] points, int i, int j) {
        return (points[i][0] - points[j][0]) * (points[i][0] - points[j][0]) +
                (points[i][1] - points[j][1]) * (points[i][1] - points[j][1]);
    }
}

 

posted @ 2020-12-11 21:41  不学无墅_NKer  阅读(111)  评论(0编辑  收藏  举报