暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

【每日一题】447. 回旋镖的数量:暴力枚举 & 哈希表!

彤哥来刷题啦 2021-09-13
170

今天是我坚持写题解的第 40 天!

题目描述(Medium)

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

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

示例 1:

输入:points = [[0,0],[1,0],[2,0]] 

输出:2

解释:两个回旋镖为 [[1,0],[0,0],[2,0]] 和 [[1,0],[2,0],[0,0]]

示例 2:

输入:points = [[1,1],[2,2],[3,3]] 

输出:2

示例 3:

输入:points = [[1,1]] 

输出:0

提示:

n == points.length
1 <= n <= 500
points[i].length == 2
-10^4 <= xi, yi <= 10^4
所有点都 互不相同

链接:https://leetcode-cn.com/problems/number-of-boomerangs

方法、暴力枚举 + 哈希表

题目给定的数据最多只有 500 个,所以,这道题我们可以暴力枚举每个点,记录其他点与它的距离,距离相等的就说明可以组合成一个回旋镖,我们只需要记录每个距离有多少个就可以很方便地计算出回旋镖的总数,题目明确说了需要考虑元组的顺序,所以,我们使用排列从距离相等的点中取两个。

关于每个距离的数量的存储,当然使用哈希表啦。

请看代码:

class Solution {
    public int numberOfBoomerangs(int[][] points) {
        // 看数据范围只有500,所以,直接枚举每个点,算其他点与它的距离,分组整理
        // 然后统计每个距离有多少个,从其中取两个即可
        int ans = 0;

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

        int n = points.length;
        for (int i = 0; i < n; i++) {
            int[] p0 = points[i];
            for (int j = 0; j < n; j++) {
                if (i != j) {
                    int[] p1 = points[j];
                    int deltaX = p0[0] - p1[0];
                    int deltaY = p0[1] - p1[1];
                    // distance = (x1-x2)^2 + (y1-y2)^2
                    int distance = deltaX * deltaX + deltaY * deltaY;
                    map.put(distance, map.getOrDefault(distance, 0) + 1);
                }
            }

            // 排列:距离相等的取两个
            for (int val : map.values()) {
                ans += val * (val - 1);
            }

            // 清空map供下一轮使用
            map.clear();
        }

        return ans;
    }
}

  • 时间复杂度:,两层循环。
  • 空间复杂度:,map最多占用 的额外空间。

运行结果如下:

image-20210913104909988

最后

如果对你有帮助,请点个赞吧,谢谢^^

也可以关注我,每日分享题解,一起刷题,一起拿全家桶。

文章转载自彤哥来刷题啦,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论