题目描述
思路解析动画文字版
口诀记牢:每个点轮流当中心,按距离把其余点分组,某距离上有 m 个点就贡献 m×(m−1)。下面每一帧都在套它。
先固定第 0 个点 (1,1) 当中心(紫色)。接下来量它到另外 4 个点的距离,按距离分组记到右边的距离表里。
量到第 1 个点 (0,1)(绿色),平方距离是 1。距离 1 第一次出现,登记 1 个点。
量到第 2 个点 (2,1)(绿色),平方距离是 1。距离 1 又来一个,现在这条距离上累计 2 个点,它们彼此能和中心配成回旋镖。
量到第 3 个点 (1,0)(绿色),平方距离是 1。距离 1 又来一个,现在这条距离上累计 3 个点,它们彼此能和中心配成回旋镖。
量到第 4 个点 (1,2)(绿色),平方距离是 1。距离 1 又来一个,现在这条距离上累计 4 个点,它们彼此能和中心配成回旋镖。
中心 (1,1) 量完:四个点全落在距离 1 上,m = 4。讲顺序地从这 4 个里挑两个,共 4×3 = 12 个回旋镖。答案累计到 12。
换第 1 个点 (0,1) 当中心。注意每换一个中心,距离表都要清空重来,距离是相对当前中心算的。
量到 (1,1),平方距离 1。距离 1 记 1 个。
量到 (2,1),平方距离 4。距离 4 记 1 个。
量到 (1,0),平方距离 2。距离 2 记 1 个。
量到 (1,2),平方距离 2。距离 2 这下凑到 2 个点了,它们能和中心 (0,1) 组成回旋镖。
中心 (0,1) 量完:只有距离 2 上落了 2 个点,贡献 2×1 = 2,别的距离各只 1 个点配不成对。答案累计到 14。
第 3 个中心 (2,1),流程一样:清空距离表,逐个量距离。
量到 (1,1),平方距离 1,距离 1 累计 1 个点。
量到 (0,1),平方距离 4,距离 4 累计 1 个点。
量到 (1,0),平方距离 2,距离 2 累计 1 个点。
量到 (1,2),平方距离 2,距离 2 累计 2 个点。
中心 (2,1) 同样在距离 2 上凑到 2 个点,贡献 2。答案累计到 16。
第 4 个中心 (1,0) 和前面对称,过程一样,直接看分组结果:距离 1: 1 个点,距离 2: 2 个点,距离 4: 1 个点。
中心 (1,0) 在距离 2 上有 2 个点,贡献 2。答案累计到 18。
第 5 个中心 (1,2) 和前面对称,过程一样,直接看分组结果:距离 1: 1 个点,距离 2: 2 个点,距离 4: 1 个点。
中心 (1,2) 在距离 2 上有 2 个点,贡献 2。答案累计到 20。
五个点各当一次中心,把贡献全加起来:中心 (1,1) 贡献 12,另外四个各贡献 2,合计 20。这就是答案。
边界先想清:点太少为 0、距离全不同为 0、同距离 m 个点贡献 m×(m−1)。
面试重点:约束挂在中心上,固定中心 + 哈希分组把一层枚举省掉。
参考代码
from __future__ import annotationsfrom typing import *from collections import *from functools import *from itertools import *from math import *from heapq import *from bisect import *class Solution: def numberOfBoomerangs(self, points: List[List[int]]) -> int: ans = 0 for p1 in points: cnt = Counter() for p2 in points: d = dist(p1, p2) ans += cnt[d] cnt[d] += 1 return ans << 1复杂度
- 时间:O(n²),每个点当一次中心,各自再扫一遍所有点
- 空间:O(n),每个中心一张距离哈希表,最多 n 项
易错点
面试追问把动画讲成自己的话
追问为什么枚举「中心点」而不是枚举点对,能从 O(n³) 降到 O(n²)?
追问这题还能更快吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
最小操作次数使数组元素相等
LeetCode 453 · 中等 · 沿着 数组套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题