news 2026/4/18 6:33:05

LeetCode 447 - 回旋镖的数量

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LeetCode 447 - 回旋镖的数量


文章目录

    • 摘要
    • 描述
    • 题解答案
    • 题解代码分析
    • 题解代码分析(深入讲讲思路)
      • 为什么使用平方距离?
      • 为什么需要用字典统计?
      • 为什么是 `count * (count - 1)`?
    • 示例测试及结果
      • 示例 1
      • 示例 2
      • 示例 3
    • 时间复杂度
      • O(n²)
    • 空间复杂度
      • O(n)
    • 总结

摘要

这一题是典型的几何 + 哈希表计数问题,属于 LeetCode 算法里的中等偏简单类型。但真正理解它的本质,会让你在之后处理“点对点距离分类”“组合数计算”这类题时变得非常轻松。

题目要求我们统计二维平面里的所有“回旋镖”数量。只要三个点中的两个点与中心点的距离一样(而且顺序不同算不同),就能形成一个有效的回旋镖。

我们会从直觉出发,用一种非常贴近开发者思维的方式讲清楚解法,并给出 Swift 可运行 Demo 代码。

描述

你会拿到一个 n 个点组成的数组,每个点是[x, y]。如果从一个点 i 出发,有两个不同的点 j、k 到它的距离相同,那么(i, j, k)就构成一个回旋镖,而且顺序不同的是不同的回旋镖。

比如:

points = [[0,0],[1,0],[2,0]]

(1,0)为中心点:

  • (0,0)距离是 1
  • (2,0)距离也是 1

所以(1,0) -> (0,0) -> (2,0)(1,0) -> (2,0) -> (0,0)都是回旋镖,总共2 个

题解答案

核心逻辑很简单:

  1. 选一个点作为“中心点 i”

  2. 计算它到所有其他点的距离

  3. 把相同距离的点统计在一起

    • 比如对 i 来说,有 3 个点距离都相同
  4. 假设某个距离下有m个点

    • 这些点能构成m * (m - 1)个回旋镖
      因为(i, j, k)(i, k, j)都算合法

然后把所有 i 当作中心点统计即可。

题解代码分析

下面给出的 Swift 代码是可直接运行的版本。

importFoundationclassSolution{funcnumberOfBoomerangs(_points:[[Int]])->Int{letn=points.countifn<3{return0}varresult=0foriin0..<n{vardistanceCount=[Int:Int]()forjin0..<n{ifi==j{continue}letdx=points[i][0]-points[j][0]letdy=points[i][1]-points[j][1]letdist=dx*dx+dy*dy// 用平方距离即可distanceCount[dist,default:0]+=1}// 对每个距离进行组合计数for(_,count)indistanceCount{ifcount>1{result+=count*(count-1)}}}returnresult}}// MARK: - Demo 代码(可运行)letsolution=Solution()print("示例 1:",solution.numberOfBoomerangs([[0,0],[1,0],[2,0]]))// 2print("示例 2:",solution.numberOfBoomerangs([[1,1],[2,2],[3,3]]))// 2print("示例 3:",solution.numberOfBoomerangs([[1,1]]))// 0

题解代码分析(深入讲讲思路)

为什么使用平方距离?

我们并不需要开方,因为只要相等即可,平方距离能减少浮点误差,也让计算更快。

为什么需要用字典统计?

因为以某个点 i 为中心,我们要知道:

  • 和它距离相同的点数量是多少?

例如 i 到三个不同点距离为 5:

count = 3 可构成 3 * 2 = 6 个回旋镖 (i,j,k), (i,k,j) ... 等

为什么是count * (count - 1)

因为这是排列数,不是组合。

顺序不同算不同(题目强调了元组顺序重要)。

示例测试及结果

示例 1

输入:[[0,0],[1,0],[2,0]] 输出:2 解释: 中心点 (1,0) 和其他两个点距离相等 所以 (i,j,k)、(i,k,j) 两种排列

示例 2

输入:[[1,1],[2,2],[3,3]] 输出:2 解释: 所有点呈现对角线方向 每个点与其他两点等距(斜率一致)

示例 3

输入:[[1,1]] 输出:0 解释:单点无法构成任何回旋镖

以上示例已包含在 Demo 代码里,可直接运行验证。

时间复杂度

O(n²)

原因:

  • 对每个点 i(共有 n 个)
  • 遍历所有点 j(每次 n 次)
  • 总共 n² 操作

空间复杂度

O(n)

因为我们用一个字典记录与中心点的距离统计,最坏情况下记录 n−1 个距离。

总结

这道题看似几何题,其实本质是“基于中心点的等距离分组 + 排列数统计”,属于非常典型的哈希计数思想。

你可以从这题总结几个通用技巧:

  1. 只要是几何题里要求判断距离是否相等,就用平方距离代替真正距离。
  2. 当题目中顺序重要时,通常是排列问题,count * (count - 1)是常客。
  3. 对每个点单独作为中心点做统计,是一种很高效的枚举方式。

在实际工程里,如果你在做地图平台、运动分析、用户定位聚类、甚至是某些推荐系统的空间距离处理时,这类“距离分类统计”的思想都能派上用场。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/1 11:37:23

成都顶级游资泄密:颠覆你认知的5条短线铁律

引言&#xff1a;为何听了那么多道理&#xff0c;依旧在亏钱&#xff1f;你是否也曾经历这样的循环&#xff1a;花无数个夜晚研究K线&#xff0c;把各种技术指标烂熟于心&#xff0c;偶尔抓住一两个涨停便心生希望&#xff0c;但最终&#xff0c;一次猝不及及的大跌就足以吞噬掉…

作者头像 李华
网站建设 2026/4/11 1:58:49

晶体塑性有限元显示动力学cpfem_vumat子程序(界面调用程序)

晶体塑性有限元显示动力学cpfem_vumat子注意此程序为\"界面调用程序\"&#xff0c;用于显示动力学。最近在搞晶体塑性有限元仿真的时候&#xff0c;发现显式动力学框架下的材料子程序开发真是个磨人的小妖精。特别是那个cpfem_vumat&#xff0c;说是"界面调用程…

作者头像 李华
网站建设 2026/4/18 5:15:35

基于R语言BIOMOD2 及机器学习方法的物种分布模拟与案例分析

查看原文>>> https://mp.weixin.qq.com/s/zNmqmmfkFq-I8DFRIKzt6A 【目标】&#xff1a; 1、理解物种分布模型的基本原理&#xff1a;理解物种分布模型&#xff08;SDMs&#xff09;的理论基础&#xff0c;包括模型的种类、用途以及在生态研究和环境管理中的应用。 …

作者头像 李华
网站建设 2026/4/18 6:24:16

pr 批量修改字幕样式的方法,简单又实用

做视频剪辑的人都知道&#xff1a;字幕样式统一&#xff0c;是让作品更专业的关键步骤。 但现实却是——很多新手剪辑师遇到字幕内容多、样式需要统一修改时&#xff0c;总会被 PR 的复杂操作折磨得头痛不已。 作为一直深耕 PR 剪辑的作者&#xff0c;我也遇到过类似问题&#…

作者头像 李华
网站建设 2026/4/18 6:25:09

基于非下采样轮廓波变换的图像融合

1. 概述 非下采样轮廓波变换(Non-Subsampled Contourlet Transform, NSCT)是一种多尺度、多方向的图像表示方法&#xff0c;能够有效地捕捉图像中的几何结构信息。基于NSCT的图像融合方法因其优秀的性能在医学成像、遥感图像处理等领域得到了广泛应用。 2. NSCT基本原理 2.1…

作者头像 李华